Kenpachi Posted November 15, 2011 Group: Members Topic Count: 22 Topics Per Day: 0.00 Content Count: 764 Reputation: 220 Joined: 11/14/11 Last Seen: November 19, 2020 Share Posted November 15, 2011 Hi. Can someone share a list with the position of sprites in relation to the body? (For example: head, hair, headgear, weapon, and so on...) I hope you understand what I'm asking for.... otherwise ask for details please. Quote Link to comment Share on other sites More sharing options...
0 GodLesZ Posted November 15, 2011 Group: Members Topic Count: 1 Topics Per Day: 0.00 Content Count: 186 Reputation: 51 Joined: 11/14/11 Last Seen: January 21, 2015 Share Posted November 15, 2011 (edited) Hi. Can someone share a list with the position of sprites in relation to the body? (For example: head, hair, headgear, weapon, and so on...) I hope you understand what I'm asking for.... otherwise ask for details please. My PHP sprite class draws them some sort of dynamic: public function drawPart($pallette, $data, $sizeX, $sizeY, $offX, $offY, $round) { $i = 0; $x = (self::$IMAGE_WIDTH / 2); $x -= ($round == true ? round($sizeX / 2) : $sizeX / 2); $y = self::$IMAGE_BASEOFF; if ($this->charOption == 32) { $y += 10; } if ($this->charOption == 16) { $y += 30; } $y -= ($round == true ? round($sizeY / 2) : $sizeY / 2); while ($i < strlen($data)) { $entry = $pallette[hexdec(substr($data, $i, 2))]; $pal = imageColorAllocateAlpha($this->ImageObj, $entry['r'], $entry['g'], $entry['b'], $entry['a']); imageSetPixel($this->ImageObj, $offX + $x, $offY + $y, $pal); $i += 2; $x++; if (($i / 2) % $sizeX == 0) { $y++; $x = (self::$IMAGE_WIDTH / 2); $x -= ($round == true ? round($sizeX / 2) : $sizeX / 2); } } } While the parameter/arguments are something screwed up.. i never had time to clean this up, but her is a the whole drawing: public function drawHead($internal = false, $bodyextraX = 0, $bodyextraY = 0) { if ($internal == false) { $this->ImageObj = ImageCreateTrueColor(self::$IMAGE_WIDTH, self::$IMAGE_HEIGHT); ImageSaveAlpha($this->ImageObj, true); ImageFill($this->ImageObj, 0, 0, ImageColorAllocateAlpha($this->ImageObj, 255, 0, 255, 127)); } // Head $this->HEAD_ACT = RagnarokActionFormat::structFromFile(self::$DATA_FOLDER . 'sprite/Àΰ£Á·/¸Ó¸®Åë/'.$this->getSpriteSex().'/'.self::$HAIR_IDS[$this->charSex][$this->charHair].'_'.$this->getSpriteSex() . '.act'); $this->HEAD_SPR = RagnarokSpriteFormat::structFromFile(self::$DATA_FOLDER . 'sprite/Àΰ£Á·/¸Ó¸®Åë/'.$this->getSpriteSex().'/'.self::$HAIR_IDS[$this->charSex][$this->charHair].'_'.$this->getSpriteSex() . '.spr'); if (isset($this->charHair_color) && $this->charHair_color != 0) { $this->HEAD_PAL = RagnarokPaletteFormat::structFromFile(self::$DATA_FOLDER . 'palette/¸Ó¸®/¸Ó¸®'.self::$HAIR_IDS[$this->charSex][$this->charHair].'_'.$this->getSpriteSex().'_'.$this->charHair_color.'.pal'); } else { $this->HEAD_PAL = RagnarokPaletteFormat::structFromFile(self::$DATA_FOLDER . 'sprite/Àΰ£Á·/¸Ó¸®Åë/'.$this->getSpriteSex().'/'.self::$HAIR_IDS[$this->charSex][$this->charHair].'_'.$this->getSpriteSex().'.spr'); } $headoffsetX = $this->HEAD_ACT['animations'][$this->getFrameNo()]['frames'][1]['subframes'][1]['offsetX']; $headoffsetY = $this->HEAD_ACT['animations'][$this->getFrameNo()]['frames'][1]['subframes'][1]['offsetY']; $headextraX = $this->HEAD_ACT['animations'][$this->getFrameNo()]['frames'][1]['extraX']; $headextraY = $this->HEAD_ACT['animations'][$this->getFrameNo()]['frames'][1]['extraY']; $newheadoffsetX = $headoffsetX + $bodyextraX - $headextraX; $newheadoffsetY = $headoffsetY + $bodyextraY - $headextraY; // draw head $this->drawPart($this->HEAD_PAL, $this->getHeadSpr('Extracted_Data'), $this->getHeadSpr('Size_X'), $this->getHeadSpr('Size_Y'), $newheadoffsetX, $newheadoffsetY, false); // Headgear if ($this->charHead_top != 0) { $this->HEADT_ACT = RagnarokActionFormat::structFromFile(self::$DATA_FOLDER . 'sprite/¾Ç¼¼»Ç¸®/'.$this->getSpriteSex().'/'.$this->getSpriteSex().'_'.$this->getSpriteHeadName($this->charHead_top) . '.act'); $this->HEADT_SPR = RagnarokSpriteFormat::structFromFile(self::$DATA_FOLDER . 'sprite/¾Ç¼¼»Ç¸®/'.$this->getSpriteSex().'/'.$this->getSpriteSex().'_'.$this->getSpriteHeadName($this->charHead_top) . '.spr'); $this->HEADT_PAL = RagnarokPaletteFormat::structFromFile(self::$DATA_FOLDER . 'sprite/¾Ç¼¼»Ç¸®/'.$this->getSpriteSex().'/'.$this->getSpriteSex().'_'.$this->getSpriteHeadName($this->charHead_top) . '.spr'); $head_topoffsetX = $this->HEADT_ACT['animations'][$this->getFrameNo()]['frames'][1]['subframes'][1]['offsetX']; $head_topoffsetY = $this->HEADT_ACT['animations'][$this->getFrameNo()]['frames'][1]['subframes'][1]['offsetY']; $head_topextraX = $this->HEADT_ACT['animations'][$this->getFrameNo()]['frames'][1]['extraX']; $head_topextraY = $this->HEADT_ACT['animations'][$this->getFrameNo()]['frames'][1]['extraY']; $newhead_topoffsetX = $head_topoffsetX + $bodyextraX - $head_topextraX; $newhead_topoffsetY = $head_topoffsetY + $bodyextraY - $head_topextraY; } if ($this->charHead_mid != 0) { $this->HEADM_ACT = RagnarokActionFormat::structFromFile(self::$DATA_FOLDER . 'sprite/¾Ç¼¼»Ç¸®/'.$this->getSpriteSex().'/'.$this->getSpriteSex().'_'.$this->getSpriteHeadName($this->charHead_mid) . '.act'); $this->HEADM_SPR = RagnarokSpriteFormat::structFromFile(self::$DATA_FOLDER . 'sprite/¾Ç¼¼»Ç¸®/'.$this->getSpriteSex().'/'.$this->getSpriteSex().'_'.$this->getSpriteHeadName($this->charHead_mid) . '.spr'); $this->HEADM_PAL = RagnarokPaletteFormat::structFromFile(self::$DATA_FOLDER . 'sprite/¾Ç¼¼»Ç¸®/'.$this->getSpriteSex().'/'.$this->getSpriteSex().'_'.$this->getSpriteHeadName($this->charHead_mid) . '.spr'); $head_midoffsetX = $this->HEADM_ACT['animations'][$this->getFrameNo()]['frames'][1]['subframes'][1]['offsetX']; $head_midoffsetY = $this->HEADM_ACT['animations'][$this->getFrameNo()]['frames'][1]['subframes'][1]['offsetY']; $head_midextraX = $this->HEADM_ACT['animations'][$this->getFrameNo()]['frames'][1]['extraX']; $head_midextraY = $this->HEADM_ACT['animations'][$this->getFrameNo()]['frames'][1]['extraY']; $newhead_midoffsetX = $head_midoffsetX + $bodyextraX - $head_midextraX; $newhead_midoffsetY = $head_midoffsetY + $bodyextraY - $head_midextraY; } if ($this->charHead_bottom != 0) { $this->HEADB_ACT = RagnarokActionFormat::structFromFile(self::$DATA_FOLDER . 'sprite/¾Ç¼¼»Ç¸®/'.$this->getSpriteSex().'/'.$this->getSpriteSex().'_'.$this->getSpriteHeadName($this->charHead_bottom) . '.act'); $this->HEADB_SPR = RagnarokSpriteFormat::structFromFile(self::$DATA_FOLDER . 'sprite/¾Ç¼¼»Ç¸®/'.$this->getSpriteSex().'/'.$this->getSpriteSex().'_'.$this->getSpriteHeadName($this->charHead_bottom) . '.spr'); $this->HEADB_PAL = RagnarokPaletteFormat::structFromFile(self::$DATA_FOLDER . 'sprite/¾Ç¼¼»Ç¸®/'.$this->getSpriteSex().'/'.$this->getSpriteSex().'_'.$this->getSpriteHeadName($this->charHead_bottom) . '.spr'); $head_bottomoffsetX = $this->HEADB_ACT['animations'][$this->getFrameNo()]['frames'][1]['subframes'][1]['offsetX']; $head_bottomoffsetY = $this->HEADB_ACT['animations'][$this->getFrameNo()]['frames'][1]['subframes'][1]['offsetY']; $head_bottomextraX = $this->HEADB_ACT['animations'][$this->getFrameNo()]['frames'][1]['extraX']; $head_bottomextraY = $this->HEADB_ACT['animations'][$this->getFrameNo()]['frames'][1]['extraY']; $newhead_bottomoffsetX = $head_bottomoffsetX + $bodyextraX - $head_bottomextraX; $newhead_bottomoffsetY = $head_bottomoffsetY + $bodyextraY - $head_bottomextraY; } // draw head bottom if ($this->charHead_bottom != 0) { $this->drawPart($this->HEADB_PAL, $this->getHeadBSpr('Extracted_Data'), $this->getHeadBSpr('Size_X'), $this->getHeadBSpr('Size_Y'), $newhead_bottomoffsetX, $newhead_bottomoffsetY, true); } // draw head middle if ($this->charHead_mid != 0) { $this->drawPart($this->HEADM_PAL, $this->getHeadMSpr('Extracted_Data'), $this->getHeadMSpr('Size_X'), $this->getHeadMSpr('Size_Y'), $newhead_midoffsetX, $newhead_midoffsetY, true); } // draw head top if ($this->charHead_top != 0) { $this->drawPart($this->HEADT_PAL, $this->getHeadTSpr('Extracted_Data'), $this->getHeadTSpr('Size_X'), $this->getHeadTSpr('Size_Y'), $newhead_topoffsetX, $newhead_topoffsetY, false); } if ($internal == false) { self::Trim($this->ImageObj); } } public function drawCharacter() { $this->ImageObj = ImageCreateTrueColor(self::$IMAGE_WIDTH, self::$IMAGE_HEIGHT); ImageSaveAlpha($this->ImageObj, true); ImageFill($this->ImageObj, 0, 0, ImageColorAllocateAlpha($this->ImageObj, 255, 0, 255, 127)); // Body $this->BODY_ACT = RagnarokActionFormat::structFromFile(self::$DATA_FOLDER . 'sprite/Àΰ£Á·/¸öÅë/'.$this->getSpriteSex().'/'.$this->getSpriteBodyName().'_'.$this->getSpriteSex() . '.act'); $this->BODY_SPR = RagnarokSpriteFormat::structFromFile(self::$DATA_FOLDER . 'sprite/Àΰ£Á·/¸öÅë/'.$this->getSpriteSex().'/'.$this->getSpriteBodyName().'_'.$this->getSpriteSex() . '.spr'); // Shadow $this->SHADOW_ACT = RagnarokActionFormat::structFromFile(self::$DATA_FOLDER . 'sprite/shadow.act'); $this->SHADOW_SPR = RagnarokSpriteFormat::structFromFile(self::$DATA_FOLDER . 'sprite/shadow.spr'); $classpal_tab = array( 4011 => 10, 4009 => 8 ); if (isset($classpal_tab[$this->charClass]) && isset($this->charClothes_color) && $this->charClothes_color != 0) { $this->BODY_PAL = RagnarokPaletteFormat::structFromFile(self::$DATA_FOLDER . 'palette/¸ö/'.$CLASS_SPRITES[$classpal_tab[$this->charClass]].'_'.$this->getSpriteSex().'_'.$this->charClothes_color.'.pal'); } else { $this->BODY_PAL = RagnarokPaletteFormat::structFromFile(self::$DATA_FOLDER . 'sprite/Àΰ£Á·/¸öÅë/'.$this->getSpriteSex().'/'.$this->getSpriteBodyName().'_'.$this->getSpriteSex().'.spr'); } $this->SHADOW_PAL = RagnarokPaletteFormat::structFromFile(self::$DATA_FOLDER . 'sprite/shadow.spr', true); $bodyoffsetX = $this->BODY_ACT['animations'][$this->getFrameNo()]['frames'][1]['subframes'][1]['offsetX']; $bodyoffsetY = $this->BODY_ACT['animations'][$this->getFrameNo()]['frames'][1]['subframes'][1]['offsetY']; $bodyextraX = $this->BODY_ACT['animations'][$this->getFrameNo()]['frames'][1]['extraX']; $bodyextraY = $this->BODY_ACT['animations'][$this->getFrameNo()]['frames'][1]['extraY']; $shadowoffsetX = $this->SHADOW_ACT['animations'][1]['frames'][1]['subframes'][1]['offsetX']; $shadowoffsetY = $this->SHADOW_ACT['animations'][1]['frames'][1]['subframes'][1]['offsetY']; $newshadowoffsetX = $shadowoffsetX; $newshadowoffsetY = $shadowoffsetY; $newbodyoffsetX = $bodyoffsetX; $newbodyoffsetY = $bodyoffsetY; // draw shadow $this->drawPart($this->SHADOW_PAL, $this->getShadowSpr('Extracted_Data'), $this->getShadowSpr('Size_X'), $this->getShadowSpr('Size_Y'), $newshadowoffsetX, $newshadowoffsetY, true); // draw body $this->drawPart($this->BODY_PAL, $this->getBodySpr('Extracted_Data'), $this->getBodySpr('Size_X'), $this->getBodySpr('Size_Y'), $newbodyoffsetX, $newbodyoffsetY, true); // draw head $this->drawHead(true, $bodyextraX, $bodyextraY); self::Trim($this->ImageObj); } Its working for me but i dont know if there are some better ways for calulcating the positions. It assums that the offsetX and offsetY in action files are based on the image's center. As GDI draws based on the top-left corner, i subtract the half of width and height to get the top-left corner. The extraX and extraY in the body action file is used to offset the head sprite. This was just a test because i never read something about these 2 coordinates and after frustrating about a dynamic way for drawing a full character sprite, i tried them and yay, it worked! Hope it helps, even if its rly unclean :S €dit: spoiled x.x Edited November 15, 2011 by GodLesZ Quote Link to comment Share on other sites More sharing options...
0 Kenpachi Posted November 15, 2011 Group: Members Topic Count: 22 Topics Per Day: 0.00 Content Count: 764 Reputation: 220 Joined: 11/14/11 Last Seen: November 19, 2020 Author Share Posted November 15, 2011 PHP makes me cry! But well, I'll give it a chance. Thanks. Quote Link to comment Share on other sites More sharing options...
0 KeyWorld Posted November 15, 2011 Group: Members Topic Count: 9 Topics Per Day: 0.00 Content Count: 379 Reputation: 304 Joined: 11/10/11 Last Seen: December 2, 2014 Share Posted November 15, 2011 It's something like this : vec2 pos = size.xy*0.5 + off.xy + ( body_off2.xy - off2.xy ); Quote Link to comment Share on other sites More sharing options...
0 GodLesZ Posted November 16, 2011 Group: Members Topic Count: 1 Topics Per Day: 0.00 Content Count: 186 Reputation: 51 Joined: 11/14/11 Last Seen: January 21, 2015 Share Posted November 16, 2011 (edited) It's something like this : vec2 pos = size.xy*0.5 + off.xy + ( body_off2.xy - off2.xy ); Without the explanation of the variable names i dont think this helps alot xD I assume size is the head sprite size after apply the scale from the action, right? off may be the world offset used to draw the sprite on a specified position. body_off2 seems to hold either the offset from the body action or another world offset/position. Or maybe the extraX/extraY in the action file? off2 had to be advised. Just to test some generic algorithms (i hate pseudocode) .. // assume the image is draw from the top-left corner // -- Input -- // Contains the world position Vector2 worldPos; // Offset taken from the boady action file, most named as "extraX/extraY" Vector2 bodyExtraOffset; // Offset taken from the head action file Vector2 headOffset; // Offset taken from the head action file, most named as "extraX/extraY" Vector2 headExtraOffset; // Head image size, after apply mirror, rotation & scale modifer from action file Vector2 headImageSize; // --- Drawing --- // Calculate the final offset for drawing Vector2 finalHeadOffset = (worldPos + headOffset + bodyExtraOffset - headExtraOffset); // The offset in action files are relative to the image center, so normalize this to the top-left corner finalHeadOffset -= headImageSize * 0.5f; // Draw the image Draw(<headImage>, finalHeadOffset); Hope it helps ôo Edited November 16, 2011 by GodLesZ Quote Link to comment Share on other sites More sharing options...
0 KeyWorld Posted November 16, 2011 Group: Members Topic Count: 9 Topics Per Day: 0.00 Content Count: 379 Reputation: 304 Joined: 11/10/11 Last Seen: December 2, 2014 Share Posted November 16, 2011 Yeah off2 seems to be your extraX-extraY (and body_off2 -> body_extraX/body_extraY). Size is the sprite size store in action after apply in the order : mirror -> rotation -> scale. Quote Link to comment Share on other sites More sharing options...
0 GodLesZ Posted November 16, 2011 Group: Members Topic Count: 1 Topics Per Day: 0.00 Content Count: 186 Reputation: 51 Joined: 11/14/11 Last Seen: January 21, 2015 Share Posted November 16, 2011 Yeah off2 seems to be your extraX-extraY (and body_off2 -> body_extraX/body_extraY). Size is the sprite size store in action after apply in the order : mirror -> rotation -> scale. Thanks for pointing that out. I think my pseudocode should be correct now. Quote Link to comment Share on other sites More sharing options...
0 Kenpachi Posted November 16, 2011 Group: Members Topic Count: 22 Topics Per Day: 0.00 Content Count: 764 Reputation: 220 Joined: 11/14/11 Last Seen: November 19, 2020 Author Share Posted November 16, 2011 Thank you guys. I think this will help me a lot. Quote Link to comment Share on other sites More sharing options...
Question
Kenpachi
Hi.
Can someone share a list with the position of sprites in relation to the body? (For example: head, hair, headgear, weapon, and so on...)
I hope you understand what I'm asking for.... otherwise ask for details please.
Link to comment
Share on other sites
7 answers to this question
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.