Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Dark GDK / 2D Game Collision

Author
Message
archie456
16
Years of Service
User Offline
Joined: 13th Feb 2008
Location:
Posted: 15th May 2008 23:45
Hi,

I'm a new to c++ and game writing... I'm writing a 2D game which involves sprite collision.

The PNG files (from Photoshop) have transparent areas - I'd to have a pixel perfect collision routing which ignores these areas.

Can anyone point me to a download for this? Thanks.

dbSpriteCollision - doesn't seem to be pixel perfect and doesn't seem to work with transparency (i.e. it always detects a collision).

Thanks.
jason p sage
17
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 16th May 2008 05:02 Edited at: 16th May 2008 05:02
I've heard you need to roll your own pixel perfect stuff, but I have also heard of a dbpro plugin for really fast sprites and stuff and it might have that and maybe the author can compile it for DarkGDK if he/she hasn't already.

How many sprites you need to check. Pixel Perfect collision isn't all THAT hard as it apears at first glance. Where I think you need to be careful with it is in how many sprites at once and how big they are.

I could be wrong, but back in the commodore 64 days, there was a hardware sprite collision thing built into the CPU...imagine that huh? LOL... but I know it works by checking the "squares" that describe the overlap and then checking just those areas for collision versus scanning the whole sprite.

does that make sense? Image Attached!


Attachments

Login to view attachments
archie456
16
Years of Service
User Offline
Joined: 13th Feb 2008
Location:
Posted: 16th May 2008 11:21
I think that is a little beyond me - I'm fairly new to this stuff.

I was kinda hoping that someone would have put together a routine for this - kinda like those available for the 3D DarkGDK games.

Perhaps you could point me to some sort of tutorial on where to begin writing a routine such as this?

What does "roll your own pixel perfect stuff" mean?
jason p sage
17
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 16th May 2008 14:35
By Roll Your Own I mean create your own. Maybe someone has done it, I dunno.

It is kinda complex though for a new person... don't be discouraged, maybe someone will chime up a solution for you... in the mean time, I would tolerate the less than perfect collision so your game moves forward.. and if no one has any ideas for you after awhile - you might know enough to do this yourself or maybe someone will do this... there seems like there is a need for it

Hang in there! Be patient, maybe I'll write one ...who knows... kinda too busy ATM (at the moment).

jinzai
18
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 16th May 2008 14:55 Edited at: 16th May 2008 14:55
The Windows function IntersectRect does that very same thing. You pass in two rects and a pointer to the rect struct to place the result. The returned rect contains the overlapping region, if there is any.

If all of the pixels in that region are transparent, there is no collision.

Probably the GDK has something, too.
tneva82
16
Years of Service
User Offline
Joined: 7th May 2008
Location:
Posted: 16th May 2008 15:25
Quote: "
It is kinda complex though for a new person...
"


Just wait until you get to AI

Still dreading that phase of my project...Somewhat semi-sensible AI for 3d space flight game? Yikes!
jason p sage
17
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 16th May 2008 15:59
@archie456 - That Intersect Rect thing in the win32 api is probably worth a look like JinZai said.

The idea is this:

You have the coordinates for two sprites. Sprite A, Sprite B, XY's for each: SAX, SAY, SBX, SBY.

You should be able to ascertain each sprite's width and Height: SAW, SAH, SBW, SBH.

You need to do some testing to see if the two sprites in question are overlapping.... But HERE you can CHEAT and leverage the sprite collision that GDK has that is as you say, NOT PIXEL PERFECT (Pixel Perfect probably thinks we're talking about him LOL )

So let's say you know for a FACT two sprites hit each other.... You have a puzzle to figure out... and this is where you put your helmet on because its going to take you a while to get it.. but you will learn ALOT by the time you get this.

Hints/suggestions: its easier than it looks, but to get it DEAD on right, you will need to display alot of info to the screen so you can manually check if things jive. It will take quite a few iterations of compiling, testing, banging head on wall etc. Also, I wouldn't do this in your game code, I'd make a test application that is just for researching this and testing it. Once you get it under your belt, then incorporate it into your game).

First

You need to take SAX - SBX to gauge how far apart they are..... This result will be positive or negative and this will be important. As it will tell you which sprite is on the left. and right...... Your code needs to deal with ZERO properly also (when they are dead on exactly in same X position.

You Will need to do the same thing for the "Y" positions: SAY - SBY

To find the Rect, you need to use the widths, hieght, and these two math results above to figure out the "square" for BOTH sprites! By SQUARE I mean the X,Y and Width and Height INSIDE Each Sprite where the sprite "collision" or "overlap" is. In other words, you need to find out where the yellow is in the red sprite and the green sprite in the picture I posted Above.

If you get that working... Myself or someone else will gladly elaborate. Short of that we need to see if something is already written - sometimes people just come accross a thread and say:

GUYS! I HAVE THAT! ... They always seem to throw in... or imply a ...Besides, these other people are telling you it wrong anyways...

Seriously, if you decide you want to tackle this and show some determination by getting this part working... that performance is a motivater for people to sit down and explain more advanced things.

If you choose to say "NO WAY! I'm not doing it" there is NO SHAME in that either!

Good Luck on your game! Game coding is fun! (usually)

archie456
16
Years of Service
User Offline
Joined: 13th Feb 2008
Location:
Posted: 16th May 2008 16:38
Jason - thats for the information.

I'm slightly confused - I can't work out the difference between what your describing and dbSpriteCollision?

What I need is a collision which will not detect a hit when one sprite moves over the transparent area of another.

(Essentially I'm writing a test game where a spaceship flies through a cave - one sprite is the spaceship and another is a large picture of a cave - the transparent areas are the spaces in the cae which the ship flies through).

I though (wrongly) that dbSpriteCollision? would be clever enough to ignore the transparent areas...

... With just 2 sprites it is very easy - but I'm thinking now that I will have to put in loads of 'collision' sprites (probably just black squares) hidden from view to detect the collisions and either detect a collision with your method or dbSpriteCollision.

The other alternative I thought about would be to use a 'mask' sprite which is just black and white and somehow detect the colour of the pixel which is behind the spaceship - a hit would be the black areas...

Not too sure how you detect a pixels colour in DarkGDK...
jason p sage
17
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 16th May 2008 19:45 Edited at: 16th May 2008 19:45
Quote: "Jason - thats for the information."
I presume you mean thanx.. I mistype all the time and you're welcome!

Quote: "I'm slightly confused "
Well I'm very confused, don't feel bad!

Quote: " can't work out the difference between what your describing and dbSpriteCollision?"
Maybe I wasn't clear enough. The GDK Collision is not what you want but can help with devising pixel perfect collision in that it can be used to optimize how your collision works by first testing for a GDK sprite collision, and if there is one... then take thoe two collided sprites, and do the pixelperfect test to see if its actually a collision you care about. In trying to keep things running smooth, you want to avoid the pixel perfect check unless you at least know its required (they are overlapping? then its required!)


Quote: "What I need is a collision which will not detect a hit when one sprite moves over the transparent area of another."
I know

Quote: "(Essentially I'm writing a test game where a spaceship flies through a cave - one sprite is the spaceship and another is a large picture of a cave - the transparent areas are the spaces in the cae which the ship flies through)."
sounds cool, and I think you should consider looking into timer based movement etc... so you can keep your game running as smooth as possible on different quality PC's when you can...

Quote: "I though (wrongly) that dbSpriteCollision? would be clever enough to ignore the transparent areas..."
yeah, but maybe there is something like JenZai recommended..... have you really perused the help? I dunno.. haven't used this much.

Quote: "The other alternative I thought about would be to use a 'mask' sprite which is just black and white and somehow detect the colour of the pixel which is behind the spaceship - a hit would be the black areas..."
Now you're thinking! But, frankly in this case... I could be wrong but, the same kind of pixel checking you would need to do would be just as "heavy" as what I propose which is basically the same thing but the rectangle finding business is worth it because then you aren't scanning for hits in every pixel.. just those pixels between the two sprites that are truly overlapping. (The Yellow area above which represents the SPRITE A overlapped square (you would check against the..) and the SPRITE B overlapped square.

Quote: "Not too sure how you detect a pixels colour in DarkGDK... "
its so slow I'd forget it.. but your welcome to inventigate! inventigate! <-- Typo = New WORD! I like it!

Lilith
16
Years of Service
User Offline
Joined: 12th Feb 2008
Location: Dallas, TX
Posted: 16th May 2008 21:14
I'm going to jump into this, though I'm not ready to tackle the exact code just yet.

It seems what you need to do is determine the rectangle in each sprite/image that's involved in the overlap. The math for this should be relatively simple. Choose one rectangle and step through each pixel. If it's the transparent color, move to the next one. And so on. If you hit a non-transparent color, check for the corresponding pixel in the other image. If it isn't the transparent color either, you've got a match. Of course, this means at least a one pixel overlap. In many/most cases this can't be avoided since, in order to have any semblance of variable speed you have to move more than one pixel at a time.

If you need to consider a collision as the two objects just touching, you'd have to expand the search area to cover all nine neighborhood pixels.

I can probably work out some code on this later but I'll have to find the time. And it won't work if the sprite is scaling the image.

Lilith, Night Butterfly
I'm not a programmer but I play one in the office
jason p sage
17
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 16th May 2008 21:55
LOL - thats part two! I'm hoping he's up to the challenge of finding the overlapping rect positions in each sprite first

archie456
16
Years of Service
User Offline
Joined: 13th Feb 2008
Location:
Posted: 16th May 2008 22:02
OK - If I understand you chaps correctly this is what I think I should be doing.

ship_x_pos = the ship's x position
ship_y_pos = the ship's y position

ship_x_size = the ship's sprite width
ship_y_size = the ship's sprite height

background_x_pos = the backgrounds position on screen (will be 0)
background_y_pos = the backgrounds position on screen (will be 0)

background_x_size = backgrounds x width
background_y_size = backgrounds y width

So, essentially, from the ship's position examine the equivelent area (i.e. position + width) on the background sprite and determine the colour of the pixels - if they are, say, black then move ship as per key press...

One question - how would I return the colour of a pixel from a sprite - i.e. what DarkGDK command would I use to return the colour of a pixel at position x,y of a sprite??


Looking through the DarkGDK commands - perhaps a simpler (for me!) method would be to use dbPoint - and select, say, 4 pixels around the on screen position of the ship - dbPoint will return the colour from the screen (according to the help file) and if its black then move the ship.
jason p sage
17
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 16th May 2008 22:14
Ok... you got the right idea... I'll tell ya LOL

1st... make life easier by having sprite be same size as image - like Lilith said, no scaling.

(Lilith might have a fancier way to do this she has been studying the directx formats and stuff...but...I digress)

2: for each image, make a corresponding memblock... using dbMakeMemblockFromImage command.

3: format for this memblock is: 1st dword, image width, 2nd dword image hieght, 3rd dword depth usually 32 in my GDK experience.

after that, all the dwords are pixels. a dword is four bytes, so remember first dword is position 0, 2nd position4, etc.

Attached is a Computer 101 thing I wrote in word.. use open office if you dont have word.

Which one is RGB or Alpha I forget... but... experiment...

Attachments

Login to view attachments
jason p sage
17
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 16th May 2008 22:18
oh... and alpha zero is transparent also! and r,g,b, can be anything. in your case, if color key is 0,0,0, then rgb need to be 0,0,0 for you to consider them transparent... that goes for alpha! Alpha zero? don't bother checking - its transparent... if alpha nonzero - then check r,g,b against color key...

oh... here is what I use to access the rgba....

JGC_RGBA.H


JGC_RGBA.CPP


you're on your way man!

archie456
16
Years of Service
User Offline
Joined: 13th Feb 2008
Location:
Posted: 16th May 2008 22:50
Excellent - thanks for that.

I've not used memblock before and so I'll have to do a bit of reading!

Just out of interest - what did you think of the second solutions of using dbPoint as I mentioned in my post above - the one above this one??
jason p sage
17
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 17th May 2008 00:34
Quote: "Just out of interest - what did you think of the second solutions of using dbPoint as I mentioned in my post above - the one above this one?? "


I like the idea. I think you're approaching this laterally and with an open mind. Your idea was not shot down as a bad idea - trust me!

That idea defaintely has merit it was just wasn't looking promising from a speed point of view due to the fact that picking and placing pixels on the screen directly is simply not that fast. You would would it would be, and let me tell you, in the days of programming directly to video card memory... your idea might of been just the trick.

I had this Radar thing I made in DBPro... I was still newb'ing because I hadn't used DBPro for a couple years... anyway... the Radar I got working... even the dots for the bad guys - distances looked right YAY!... BUT holy COW did my frame rates TANK! Now, I can with hindsight and more knowledge now look back and say it was probably the big black box I drew to put the dots in or the distance checking math - as there wasn't many "dots" but definately - the DBPro Drawing to screen stuff wasn't that fast, and I read in the forums that it wasn't so good...

this is why I'm promoting ideas where 1st you see if you MUST run more code -- (using native DarkGDK Sprite Collision to see if there is possible sprite overlap) -- then using math to find the smallest amount of data possible to process (the yellow overlapped business) - and then ONLY THEN drilling down into the memblock and checking colors , r,g,b,alpha for the collision it self.

Let me warn you that the bigger the sprite - the LONGER the checks will take!!!! So you're Cave? I recommend chopping it up for performance reasons ... OR... thinking outside the box one more time to cheat....

Perhaps.... Perhaps... a "prerecorded" list of x,y values for the top and bottom of the cave that the ship MUST be inbetween at all the positions in the map! This would require you first draw your caves, then make a programming using your point ides to find the top and bottom (flyable) region for every "x" position in your level.. not x=screen coord, X=where in your cave.... Now of course... the x,y, of the cave isn't good enough... the x,y, list you need needs to be where your spaceship is... and for each location the "visual" spaceship can not be touching the cave!

Another Cheap way - sloppy'r but might do the trick is have invisible tiny sprite "pixels" along the edges of the cave.. (only in the visible region to try and save SOME resources) and if the ship hits these "fake boundries" you could do that.

I like the idea of pixel perfect sprite collision, but the numbered method is probably the fastest from a processing perspective but also the most work (well.. the sprite dot thing is kinda haneous) to get working... you'd need a utility to load the cave and space ship ... use those to calculate the "valid ranges" in your cave for the sprite, save them.... and make your game spart enough to load them OR... take all the numbers, and actuallly hardcode them in your program once its tested and perfect... so people don't hack your level if that is a concern.

Good luck Luke - May the force be with you....in that cave!

Lilith
16
Years of Service
User Offline
Joined: 12th Feb 2008
Location: Dallas, TX
Posted: 17th May 2008 00:52
Quote: "screen directly is simply not that fast."

If you're picking picking points off the screen it's going to show you one image or the other, not the individual points of each sprite in contention.

Or am I looking at this wrong?

Lilith, Night Butterfly
I'm not a programmer but I play one in the office
jason p sage
17
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 17th May 2008 00:55
you're not wrong but he was talking about comparing it against a mask - which could be implemented a few different ways... so I didn't question that. In theory he could have two bitmaps - one you see and one you don't.

Core2uu
16
Years of Service
User Offline
Joined: 15th Mar 2008
Location: Saskatoon, SK, Canada
Posted: 17th May 2008 02:45
Quote: "use open office if you dont have word."


You're going to make him DOWNLOAD open office?!?!?! WHAT'S WRONG WITH WORDPAD???

~~It's not who you are underneath, but what you do that defines you.~~
jason p sage
17
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 17th May 2008 03:49
Quote: "You're going to make him DOWNLOAD open office?!?!?!"

No.

Quote: "WHAT'S WRONG WITH WORDPAD???"

Nothing.

Quote: "~~It's not who you are underneath, but what you do that defines you.~~"

I KNEW plastic Surgery would make me a better PERSON!

Core2uu
16
Years of Service
User Offline
Joined: 15th Mar 2008
Location: Saskatoon, SK, Canada
Posted: 17th May 2008 04:03
Then why did you tell him to use open office?

Intentions + Influences = What you do ...
Plastic Surgery != What you do ...

~~It's not who you are underneath, but what you do that defines you.~~
jason p sage
17
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 17th May 2008 05:06
Dunno and LOL - I know... but I like the C++ operators

Lilith
16
Years of Service
User Offline
Joined: 12th Feb 2008
Location: Dallas, TX
Posted: 17th May 2008 06:02
Okay, this part is relatively minor. I'll have to get to the collision code sometime else during the weekend.

Assume that we define the rectangle the x/y values of the sides and top/bottom of the rectangle and put them in a struct.



The proposed function takes the rectangle of the two sprites as arguments and returns a rectangle with the co-ordinates of the common rectangle.

Here's the prototype:



And here's the function:



This will return the screen coordinates of the common rectangle where the two original rectangles overlap/intersect. If there is no overlap the area of the rectangle will be zero. Generally this means that top == bottom and left == right if there's no overlap but it is possible for there to be some edge overlap such that one width or height of the resulting rectangle is zero while the other dimension has some value.

The next attack will be to separate out the corresponding areas of the associated images. Aaaaannnnddddd, it just occurred to me that there may be a problem in reading and comparing these areas if the sprites reference the same image. I'll have to take that into account when I figure out the code.

Lilith, Night Butterfly
I'm not a programmer but I play one in the office
jason p sage
17
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 17th May 2008 06:41
Interesting approach Lilith. I thought a decent design would just have a list of sprite ID's, and matching memblock id's that were made from whatever image the sprite is. Then when testing for the overlap I wouldn't even care what the screen position was, I'd care about the rect on each image like you mentioned.

Having a function compare for collision on the same memblock should be just as easy as having 2 different ones I would suspect.

I dunno though... I wrote my library 2 times and wrote a tons of test programs... I didn't write a goldstar (perfect app - no bugs first shot) .... infact I haven't written to many goldstars ever LOL

So I'm just tosdsing theores out there.... I haven't even tried coding this like you have started to evidently

I was playing half life.. first ime.. just bought it today.. um.. pretty amazing. I haven't even held a gun yet LOL

Lilith
16
Years of Service
User Offline
Joined: 12th Feb 2008
Location: Dallas, TX
Posted: 17th May 2008 06:57
Quote: "I was playing half life.. first ime.. just bought it today.. um.. pretty amazing. I haven't even held a gun yet LOL"


I haven't really been into the 3D games that much. I used to play Doom when it first came out and advanced through things like Quake but found Quake usually whooped me on the second level and I could never get past it. So I guess I gave up on those type of games. Now I go more for the top view shooter/puzzle games. I guess I prefer testing and expanding my own limits and no so much feel like I'm competing with someone else.

Lilith, Night Butterfly
I'm not a programmer but I play one in the office
Core2uu
16
Years of Service
User Offline
Joined: 15th Mar 2008
Location: Saskatoon, SK, Canada
Posted: 17th May 2008 08:17
Quote: "but I like the C++ operators"


I didn't know how else to write does not equal... But I probably got the syntax wrong anyways LOL...

~~It's not who you are underneath, but what you do that defines you.~~
archie456
16
Years of Service
User Offline
Joined: 13th Feb 2008
Location:
Posted: 17th May 2008 19:43
Thanks for your help chaps - there a lot for me to get thinking about.

BTW: the pixel picking method - I'm thinking of something very simple - The routine would just pick 4 pxels above, left, right, below of the ship and check their colour - if its the background colour then the ship can move - if not its a wall.

It looks like I'm going to have to do a bit of learning memblocks (I come from an AutoLISP background - i.e. I write the odd routine for AutoCAD - theres a lot more to this c++ stuff!
jason p sage
17
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 19th May 2008 19:23
@archie456 -
Quote: "BTW: the pixel picking method - I'm thinking of something very simple - The routine would just pick 4 pxels above, left, right, below of the ship and check their colour - if its the background colour then the ship can move - if not its a wall."


that might work unless a misslie or explosion is happening during the read. The principle is sound, especially if only checking four dots, your "Cave" mask in another bitmap... thats not visiable might just work as you planned! (though not technically pixel-perfect collision LOL) A great idea though that might just do what you need and that's all that matters.

Lilith
16
Years of Service
User Offline
Joined: 12th Feb 2008
Location: Dallas, TX
Posted: 19th May 2008 19:25
One other problem is if you're object moves more than one pixel at a time. You might already be embedded in a wall or whatever and need to "back out" to the actually point of collision before you have the object react to the collision itself.

Lilith, Night Butterfly
I'm not a programmer but I play one in the office
archie456
16
Years of Service
User Offline
Joined: 13th Feb 2008
Location:
Posted: 19th May 2008 22:47
"One other problem is if you're object moves more than one pixel at a time. You might already be embedded in a wall or whatever and need to "back out" to the actually point of collision before you have the object react to the collision itself."

Yea - I was thinking that this might be a problem, as you say I will have sample the space the ship is going to move to rather than around the ship.
Sephnroth
22
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 20th May 2008 00:46
back in the day before I understood sprite collision and tile collision, I used to write games that used a hardness map. The idea is my hardness map was a near identical copy of the world image (i used solid large images back then) except it was 2 colour. any two colours will work but i used red for solid and black or anything else for passable.

then as my player moved around the world I kept track of the players world x/y and used that to select pixels of the hardness map and read in their rgb. if it was red then player has hit something solid.

Its not the most effcient technique in the world, but it is accurate and completely uneffected by any special effects etc going on your actual game screen

archie456
16
Years of Service
User Offline
Joined: 13th Feb 2008
Location:
Posted: 20th May 2008 00:51
Sephnroth - that sounds a good idea.

What would you think the best way of keeping track of the ships position off screen would be?

Keep the hardness map in a memblock and quiry it - or is there another way.

The reason I ask is that I need to get to know the uses of memblocks and how they work...
Mc Koding
16
Years of Service
User Offline
Joined: 13th May 2008
Location: Canada
Posted: 21st May 2008 08:03
Well go figure i am not much of a 2d person but, when doing harness map, you will need to figure out a difrent collison technuqie for missles,cannonballz, and other ships. So i would suggest go with one that can do almost all of the collisions. Or just do two things, when i finish Mc_AI i will work on a pyshics / collision libary for darkgdk for both 3d and 3d. Logiclay thats all i will do because i am lazy, and well i justed got a nose bleed.

Rendetion a farcry from DarkGDK
jason p sage
17
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 21st May 2008 18:05
Mc Koding
16
Years of Service
User Offline
Joined: 13th May 2008
Location: Canada
Posted: 21st May 2008 18:30
Bassicly , I may switch over and make a collision engine for you guys now ... BASIC ONE! Not edvanced but basic one, which repeles character from side,

Rendetion a farcry from DarkGDK
jason p sage
17
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 21st May 2008 18:34
chunks chunks
17
Years of Service
User Offline
Joined: 2nd Jan 2007
Location: ackworth uk
Posted: 21st May 2008 23:38 Edited at: 21st May 2008 23:40
here`s 2d sliding collision what i found on these forums and ported from db pro thanx to who ever wrote it.



toshiba satellite 1.6 core duo + nvidia geforce go 7300
windows vista ultimate.

Login to post a reply

Server time is: 2024-11-20 11:41:12
Your offset time is: 2024-11-20 11:41:12