Author [EN] [PL] [ES] [PT] [IT] [DE] [FR] [NL] [TR] [SR] [AR] [RU] [ID] Topic: NES-Style Castlevania Belmont Engine for GameMaker! (Version 0.3 UPDATE!)  (Read 235237 times)

0 Members and 4 Guests are viewing this topic.

Offline Inccubus

  • Wannabe Great Old One
  • Master Hunter
  • *****
  • Posts: 3287
  • Gender: Male
  • Warrior
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. SuperOld Dungeonite: Members who have been around since the oldOLD days. Permanent Resident: Seems to always be around to post/reply.
    • Awards
  • Favorite Game: Vampire Killer (MSX)
  • Likes:
Re: NES-Style Castlevania Belmont Engine for GameMaker! (Version 0.3 UPDATE!)
« Reply #270 on: February 07, 2012, 03:24:20 PM »
0
I mean the exe from Sunday. It looked perfect on my machine. (Recently upgraded BTW)
If that random 60 on the right side of the HUD is the frame counter, it never changed from 60 the entire time.

Edit: And as a matter of fact, the shortened script in the gmk runs way too fast. Also, the exe runs way smoother than CV3 running on FCEUX. Now if you'll excuse me I have to get back to work on my kilt.
« Last Edit: February 07, 2012, 03:31:58 PM by Inccubus »
"Stuff and things."

Offline TheouAegis

  • Amateur Auteur of GMvania
  • Master Hunter
  • *****
  • Posts: 1861
  • Gender: Male
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. The Great Defender will always defend the object of his or her fandom. Hack Master makes creations out of CV parts. (S)he makes Dr. Frankenstein proud.
    • GMvania Developer's Blog
    • Awards
  • Likes:
Re: NES-Style Castlevania Belmont Engine for GameMaker! (Version 0.3 UPDATE!)
« Reply #271 on: February 07, 2012, 08:36:40 PM »
0
Well shit, then. That means it's as I said; anyone using my script should give an option for running the script on slower computers. Because obviously my laptop can't handle the room transition but your computer can. Seriously, the GMK runs at the right speed more or less on my computer, whereas the EXE runs too slow.

The irony of the EXE running smoother than CV3 on FCEUX is I based it off a video recording of CV3 in FCEUX.  :-\

The benefit to this script too is it does away with many of the scripts and functions I was using in v0.3 of my engine. Although some things I do have to recode now as a result of it. That's why I released this tech demo and not the whole engine because the engine will take some time to revise to work with the transition script.


MY SCRIPT MADE IT TO THE "STAFFER'S CHOICE" SUBFORUM ON GAME MAKER COMMUNITY!  ;D 8)
« Last Edit: February 07, 2012, 10:18:28 PM by TheouAegis »
Your mom has had more floppies put in her than a Commodore 64!


Follow my lack of progress on my game at my blog:
http://gmvania.blogspot.com

Offline TheouAegis

  • Amateur Auteur of GMvania
  • Master Hunter
  • *****
  • Posts: 1861
  • Gender: Male
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. The Great Defender will always defend the object of his or her fandom. Hack Master makes creations out of CV parts. (S)he makes Dr. Frankenstein proud.
    • GMvania Developer's Blog
    • Awards
  • Likes:
Re: NES-Style Castlevania Belmont Engine for GameMaker! (Version 0.3 UPDATE!)
« Reply #272 on: February 21, 2012, 09:44:57 PM »
0
Yay! Blog update! It might not be an engine update and I might be a month late in releasing my engine when I said I would  :-X but the reason I'm so late will be apparent when you check out my blog update.

 ;D
Your mom has had more floppies put in her than a Commodore 64!


Follow my lack of progress on my game at my blog:
http://gmvania.blogspot.com

Offline TheouAegis

  • Amateur Auteur of GMvania
  • Master Hunter
  • *****
  • Posts: 1861
  • Gender: Male
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. The Great Defender will always defend the object of his or her fandom. Hack Master makes creations out of CV parts. (S)he makes Dr. Frankenstein proud.
    • GMvania Developer's Blog
    • Awards
  • Likes:
Castlevania III Password Encryptor coming to a Dungeon near you!
« Reply #273 on: February 29, 2012, 07:37:33 AM »
0
On a related note, last night I traced some RAM offsets and found most of what I need to make a Password Encryptor for CV3. The password encryption uses 7-to-9 variable bytes. Bytes $0000 and $0001 (and $0003 and $0004 when decrypting) are for temporary storage and get updated typically once every step (sometimes more often). Byte $001A simply increases by 1 each step, basically a 256-step counter; I think it's used in the encryption for some randomization element. Byte $002E is the most important; it holds the current stage. Byte $003A holds the current partner (set to -1/$FF when Trevor is alone). The trickiest byte to trace was $07F6, which holds the quest/difficulty. I still have yet to figure out what byte $078A is for; usually it's set to 0, although once I saw it set to 1 during the password encryption process and haven't been able to find code that sets it at any other time (except to 0), so maybe it's a dummy variable (and I'm the dummy).

What does all of this mean for you? Well, for starters, now you know what bytes to set in the Cheat Menu if you want to change any of those (btw byte $0035 is for Trevor's remaining lives, $003C is for his HP based on 1 bar per 4 HP, and $003D is the boss's HP). It also means when I'm done with this next side project (whose open source will be included in GMvania), you can enter any player name you want, set the difficulty, choose a partner, and pick a starting stage, then generate a password for it. You won't need to be called Okuda or Fujimoto or Akama ever again. ... But to my knowledge, only Help Me can have 10 starting lives, as that is handled by a separate subroutine. (But seeing as how I don't know what $078A is for, I could be wrong about that.)

I'm still a long way off from coding the decryptor, though. It's a little longer and messier. Since I'm still learning how to read Assembly, it's not easy.
« Last Edit: February 29, 2012, 07:39:12 AM by TheouAegis »
Your mom has had more floppies put in her than a Commodore 64!


Follow my lack of progress on my game at my blog:
http://gmvania.blogspot.com

Offline Inccubus

  • Wannabe Great Old One
  • Master Hunter
  • *****
  • Posts: 3287
  • Gender: Male
  • Warrior
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. SuperOld Dungeonite: Members who have been around since the oldOLD days. Permanent Resident: Seems to always be around to post/reply.
    • Awards
  • Favorite Game: Vampire Killer (MSX)
  • Likes:
Re: NES-Style Castlevania Belmont Engine for GameMaker! (Version 0.3 UPDATE!)
« Reply #274 on: February 29, 2012, 10:10:17 PM »
0
The hacking community will probably want that info on the password system in CV3, when you're done I encourage you to post that info at ROMHacking.net or Data Crystal or both.
"Stuff and things."

Offline TheouAegis

  • Amateur Auteur of GMvania
  • Master Hunter
  • *****
  • Posts: 1861
  • Gender: Male
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. The Great Defender will always defend the object of his or her fandom. Hack Master makes creations out of CV parts. (S)he makes Dr. Frankenstein proud.
    • GMvania Developer's Blog
    • Awards
  • Likes:
0
Sorry for lack of upload. I've had the password generator done for a while now, but when I got started on the decryption I realized some drawbacks to how GM works and changed my coding method. Wanting to keep things uniform, I decided to go back and recode the password generator to match the scripting method I'm using for the decryption. Unfortunately this means it will be harder to read and understand, but since the two are related in actual use, I decided it's best this way.

It also means I'll have to write up a guide on how to read my script because it's become so convoluted now. Seriously -- try scripting entirely with ds_grids instead of arrays and single variables like normal people. (Data Structures can be destroyed, making it more difficult for hackers to trace, or at least that's my opinion.)
Your mom has had more floppies put in her than a Commodore 64!


Follow my lack of progress on my game at my blog:
http://gmvania.blogspot.com

Offline TheouAegis

  • Amateur Auteur of GMvania
  • Master Hunter
  • *****
  • Posts: 1861
  • Gender: Male
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. The Great Defender will always defend the object of his or her fandom. Hack Master makes creations out of CV parts. (S)he makes Dr. Frankenstein proud.
    • GMvania Developer's Blog
    • Awards
  • Likes:
CV3 Encryption Code (kinda)
« Reply #276 on: March 07, 2012, 09:45:32 AM »
0
Here's the encryption code for CV3 that I've written up. DOn't know if it works yet. because I haven't tested.

Code: [Select]
/*
This script encodes the password. It must be called at the start of the Game Over's
password screen. This script is NOT used in the password entry screen.
 
Use:    pw_encrypt()
 
Simple enough, huh? The following game variables are used:
 
ally    (the current ally, use -1 or $FF for no ally)
stage   (keep in mind some stages actually take up two values)
quest   (as in whether the player is on the 2nd Quest hard mode)
 
The decryption script uses an additional optional variable:
 
path    (no idea, but it is only set for two stages for Grant)
 
The player name is carried over from the name entry via the global array name[v].
 
Numerous bitwise operations based on 6502 Assembly are used here. They are located
in the "bitwise" script group. You shouldn't mess with these, just learn how to
use them. You can figure it out by looking through this messy code.
 
In order to alter this script for your own program, you must change pw_decrypt()
and cryptos() as well, since pw_decrypt checks what this script creates and
cryptos() contains the constants used to modify the variables.
 
The comment at the top is merely for keeping track of which cells correspond to
which Zero Page byte in the original assembly code. You can ignore them.
 
Grids are used for the variables and the displayed password because they can be
easily destroyed; this won't prevent hacking, but will make it slightly harder.
Same goes for the password itself, which is stored in a list. Also, grids offer
slightly more flexibility, even if they are more tedious to deal with and take
up more RAM when created, but this is freed up after one step.
 
This was coded almost straight from the original assembly code, with a few
minor shifts of variables. If it seems convoluted and repetetive, that is
because it is, but in some cases this is necessary. There are certain
functions used in the original code that are not available in GM, so the
bitwise scripts were created to simulate some features, namely the carry bit,
stored in the variable cbit. Understanding how cbit is used is important to
understanding how this script works.
*/
 
//A=0, X=1, Y=2, 00=3, 01=4, 04=5, 05=6, 88=7, 02=8, 03=9, 89=10, 08/0f=11/18
 
temp=ds_grid_create(12,1);
ds_grid_clear(temp,0);
pwt=ds_list_create();
ds_list_add(pwt,0);
pw=ds_grid_create(4,4);
var v01a;
v01a=irandom(255);
ally &= $FF;
 
//This subscript encrypts the player name and sums up the letters. Carry flag cleared.
for(ds_grid_set(temp,1,0,0);ds_grid_get(temp,1,0)<
8;ds_grid_add(temp,1,0,1))
{
    ds_grid_set(temp,0,0,name[ds_grid_get(temp,1,0)]
);
    adc(0,cryptos(0,ds_grid_get(temp,1,0)));
    cbit=0;
    adc(0,ds_grid_get(temp,0,0));
    sta(3);
}
cbit=1;
amp(0,$7);
sta(3);
 
ds_grid_set(temp,0,0,stage);
//Change $11 to the highest resumable stage value
cmp(0,$11)
if cbit ds_grid_set(temp,0,0,$11);
stage=ds_grid_get(temp,0,0);
lsr(a);                         //  These
ds_grid_set(temp,0,0,stage);    //  lines
lsr(0);                         //  simply
rol(3);                         //  shuffle
ds_grid_set(temp,0,0,v01a);     //  cbit
lsr(0);                         //  around
repeat(3) rol(3);               //  just for this line
ds_grid_set(temp,0,0,ally);
//This checks if Accumulator is positive. Anything greater than $80 is negative.
if ds_grid_get(temp,0,0)>=$80 or ds_grid_get(temp,0,0)<0 ds_grid_set(temp,0,0,0);
ora(0,0,3);
asl(0);
ora(0,quest);
sta(7);
ds_grid_set(temp,0,0,v01a);
lsr(0);
ds_grid_set(temp,5,0,$50+$50*cbit);
 
tma(7,8);
amp(8,$F0);
tma(7);
repeat(4) asl(0);
sta(9);
cbit=0;
adc(0,0,8);
sta(4);
tma(5);
eor(0,0,8);
sta(3);
tma(5);
eor(0,0,9);
cbit=0;
adc(0,0,3)
repeat(4) lsr(0);
ora(0,0,4);
cbit=0;
adc(0,stage);
sta(10);
 
tma(7,3);
for(ds_grid_set(temp,1,0,0);ds_grid_get(temp,1,0)<
8;ds_grid_add(temp,1,0,1))
{
    lsr(3);
    rol(11+ds_grid_get(temp,1,0));
    lsr(4);
    rol(11+ds_grid_get(temp,1,0));
}
cbit=1;
ds_grid_set(temp,2,0,stage);
lsr(2);
for(ds_grid_set(temp,1,0,2);ds_grid_get(temp,1,0)>
=0;ds_grid_add(temp,1,0,-1))
{
    ds_grid_set(temp,3,0,cryptos(1,ds_grid_get(temp,2,0)));
 
    amp(3,$C);
    repeat(2) lsr(3);
    ds_grid_set(temp,0,0,cryptos(1,ds_grid_get(temp,2,0)));
 
    amp(0,$30);
    ora(0,0,3);
    if cmp(0,cryptos(2,ds_grid_get(temp,1,0)))==0 break;
}
tma(1);
repeat(3) asl(0);
adc(0,0,1);
sta(2);
for(ds_grid_set(temp,1,0,0);ds_grid_get(temp,1,0)<
9;ds_grid_add(temp,1,0,1))
{
    ds_grid_set(temp,4,0,cryptos(3,ds_grid_get(temp,2,0)+1));
 
    amp(4,$30);
    ds_grid_set(temp,0,0,cryptos(3,ds_grid_get(temp,2,0)+1))
    amp(0,$3);
    repeat(2) asl(0);
    ora(0,0,4);
    ora(0,0,11+ds_grid_get(temp,1,0));
    ds_list_add(pwt,ds_grid_get(temp,0,0));
    ds_grid_add(temp,2,0,1);
}
cbit=1;
ds_grid_set(temp,2,0,stage);
lsr(2);
ds_list_replace(pwt,0,cryptos(1,ds_grid_get(temp,2,
0)));
ds_grid_destroy(temp);

It will make more sense once I upload it. ALl that matters is "pwt" stores the actual password. Another script will translate that password into the grid we all know and love from CV3 and CV4; that script is short and sweet and I already finished coding it before I typed out this monstrosity. All the unknown 3-letter scripts are just 6502 Assembly instructions in GML script because I had to incorporate the carry bit ("cbit" in the script) into certain basic functions.

If this exacerbates your senses, then don't even think about looking at the decryption script when I upload it. It's bad enough it'll be coded by me, but the original script was pages and pages of mind-numbing assembly with branches within branches. ... This script here was straightforward by comparison.
« Last Edit: March 07, 2012, 09:48:43 AM by TheouAegis »
Your mom has had more floppies put in her than a Commodore 64!


Follow my lack of progress on my game at my blog:
http://gmvania.blogspot.com

Offline TheouAegis

  • Amateur Auteur of GMvania
  • Master Hunter
  • *****
  • Posts: 1861
  • Gender: Male
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. The Great Defender will always defend the object of his or her fandom. Hack Master makes creations out of CV parts. (S)he makes Dr. Frankenstein proud.
    • GMvania Developer's Blog
    • Awards
  • Likes:
0
Damn you, dollar sign!!
Damn you for making 50 into 80!
DAMN YOU TO HELL!!

*tries to solve all the bugs in the password generator*
Your mom has had more floppies put in her than a Commodore 64!


Follow my lack of progress on my game at my blog:
http://gmvania.blogspot.com

Offline Inccubus

  • Wannabe Great Old One
  • Master Hunter
  • *****
  • Posts: 3287
  • Gender: Male
  • Warrior
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. SuperOld Dungeonite: Members who have been around since the oldOLD days. Permanent Resident: Seems to always be around to post/reply.
    • Awards
  • Favorite Game: Vampire Killer (MSX)
  • Likes:
0
Heh heh heh. :)
"Stuff and things."

Offline TheouAegis

  • Amateur Auteur of GMvania
  • Master Hunter
  • *****
  • Posts: 1861
  • Gender: Male
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. The Great Defender will always defend the object of his or her fandom. Hack Master makes creations out of CV parts. (S)he makes Dr. Frankenstein proud.
    • GMvania Developer's Blog
    • Awards
  • Likes:
0
Spring Cleaning time. Cleaning up the code a little (finding some wasted code, unneeded variables, redundancies). Thought I finally fixed my Sprite Clipping script (the one that nobody would probably ever use if I didn't include it by default). Made it work properly with enemy torsos. Then I set image_xscale to -1 and it's still bugged.

Sometimes I wonder if mirroring sprites is worth it. I know it cuts back heavily on resources, but when you look at all the noobie posts on GMC that make you think, "Wow noob, nice waste of resources there," and then see all the follow-up posts asking how to do something while using image_xscale, it kinda makes you wonder if the resource management is worth it.

Gotta get back to debugging the script again.  :'(
Your mom has had more floppies put in her than a Commodore 64!


Follow my lack of progress on my game at my blog:
http://gmvania.blogspot.com

Offline TheouAegis

  • Amateur Auteur of GMvania
  • Master Hunter
  • *****
  • Posts: 1861
  • Gender: Male
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. The Great Defender will always defend the object of his or her fandom. Hack Master makes creations out of CV parts. (S)he makes Dr. Frankenstein proud.
    • GMvania Developer's Blog
    • Awards
  • Likes:
0
Woohoo! Finally tackled my sprite clipping script and got it working!

... As I've acknowledged many times, I'm probably the only person in the whole world that gives a rip about simulating a purely visual aspect of the Nintendo Entertainment System. (Well it wasn't purely visual, it also allowed rendering of more sprites on the screen). But screw you haters, I accomplished what I set out to do!

Special thanks to Torigara over at GMC for his advice over the months.
Your mom has had more floppies put in her than a Commodore 64!


Follow my lack of progress on my game at my blog:
http://gmvania.blogspot.com

Offline Inccubus

  • Wannabe Great Old One
  • Master Hunter
  • *****
  • Posts: 3287
  • Gender: Male
  • Warrior
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. SuperOld Dungeonite: Members who have been around since the oldOLD days. Permanent Resident: Seems to always be around to post/reply.
    • Awards
  • Favorite Game: Vampire Killer (MSX)
  • Likes:
0
As an end use I will most assuredly not ever use the sprite clipping system. On the other hand, as a programmer myself, im interested to see how you did it. Either way, congrats on getting it to work! Huzzah!
"Stuff and things."

Offline TheouAegis

  • Amateur Auteur of GMvania
  • Master Hunter
  • *****
  • Posts: 1861
  • Gender: Male
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. The Great Defender will always defend the object of his or her fandom. Hack Master makes creations out of CV parts. (S)he makes Dr. Frankenstein proud.
    • GMvania Developer's Blog
    • Awards
  • Likes:
0
Code: [Select]
//Use: draw_clipped()

//Emulate's NES limitations by clipping sprites (8x8) from metasprites on the left screen edge
if clip_sprites
{
    //NOTE: Sprite origins must be centered.
    var _lbox,_left,_wide,_xspr;
   
    //Find left edge of sprite in room   
    _lbox=x-abs(sprite_xoffset);
   
    //Check if left edge is outside view
    if _lbox<view_xview
    {
        //Calculate partial sprite pixels outside leftmost view
        _left = min(ceil((view_xview-_lbox)/(8*abs(image_xscale)))*8*abs(image_xscale),abs(sprite_width));
       
        //Calculate remaining visible pixels for full sprite
        _wide = (sprite_width-_left*sign(image_xscale))/abs(image_xscale);
       
        //Calculate the x-coordinate for the partial sprite
        _xspr = _lbox+_left;
       
        //Account for negative scaling
        _left = min(_left,sprite_width+_left)/image_xscale;
       
        //Draw the clipped sprite
        draw_sprite_part_ext(sprite_index,-1,_left,0,_wide,sprite_get_height(sprite_index),_xspr,y-sprite_get_yoffset(sprite_index),image_xscale,image_yscale,c_white,1)
       
    }
    else
    //Hide the sprite if no partials are fully visible on the right
    if _lbox+8*abs(image_xscale)<view_xview+view_wview
    {
        //Draw sprite as normal
        draw_sprite_ext(sprite_index,-1,x,y,image_xscale,image_yscale,0,c_white,1);
    }
   
    if head
    {
        //Reverse Bone Pillar's head
        var head_xscale;
        head_xscale = image_xscale;
        if object_index=obj_BonePillar
            head_xscale*=-1;
       
        //Find left edge of sprite in room   
        _lbox = x-sprite_get_xoffset(head)*abs(head_xscale);
       
        //Check if left edge is outside view
        if _lbox<view_xview
        {
            //Calculate partial sprite pixels outside leftmost view
            _left = min(ceil((view_xview-_lbox)/(8*abs(head_xscale)))*8*abs(head_xscale),abs(sprite_get_width(head)*head_xscale));
       
            //Calculate remaining visible pixels for full sprite
            _wide = (sprite_get_width(head)*head_xscale-_left*sign(head_xscale))/abs(head_xscale);
           
            //Calculate the x-coordinate for the partial sprite
            _xspr = _lbox+_left;
       
            //Account for negative scaling
            _left = min(_left,sprite_get_width(head)*head_xscale+_left)/head_xscale;
       
            //Draw the clipped sprite
            draw_sprite_part_ext(head,-1,_left,0,_wide,sprite_get_height(head),_xspr,y-sprite_yoffset-sprite_get_yoffset(head),head_xscale,image_yscale,c_white,1)       
        }
        else
        if _lbox+8*abs(head_xscale)<view_xview+view_wview
        {
            //Draw sprite as normal
            draw_sprite_ext(head,-1,x,y-sprite_yoffset,head_xscale,image_yscale,0,c_white,1);
        }
    }
}
else
{
    //Draw sprites as normal
    draw_sprite_ext(sprite_index,-1,x,y,image_xscale,image_yscale,0,c_white,1);
    if head
        if head=spr_BonePillar
            draw_sprite_ext(head,-1,x,y-sprite_yoffset,-image_xscale,image_yscale,0,c_white,1);
        else
            draw_sprite_ext(head,-1,x,y-sprite_yoffset,image_xscale,image_yscale,0,c_white,1);
}


The true beauty of my "head" method of drawing sprites larger than 16x16px becomes apparent in this script, as it should properly render any and all sprites taller than 16px.
Your mom has had more floppies put in her than a Commodore 64!


Follow my lack of progress on my game at my blog:
http://gmvania.blogspot.com

Offline TheouAegis

  • Amateur Auteur of GMvania
  • Master Hunter
  • *****
  • Posts: 1861
  • Gender: Male
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. The Great Defender will always defend the object of his or her fandom. Hack Master makes creations out of CV parts. (S)he makes Dr. Frankenstein proud.
    • GMvania Developer's Blog
    • Awards
  • Likes:
Password Generator AND Verifier early release
« Reply #283 on: April 22, 2012, 05:07:47 PM »
0
I could have put this in my other thread, but they're all related anyway.

http://www.mediafire.com/download.php?zrixfum2gz4o9h2

There's the GMK of my Password Generator & Verifier for CV3. You can see the code (at least as far as I've managed to clean it up) for not just the password generator but also the password verifier as well (the one I put off working on for so long because it was such a pain). It actually wasn't as painful as I thought it'd be, perhaps because I already figured out how to debug them when I made the generator script. It still took me quite a while -- maybe 8 or 10 hours of debugging. And then I finally narrowed it down to one of the dumbest of many follies I've foolishly committed over the weeks: confusing $0010 with #$10. If you've never worked with 6502 ASM, $0010 doesn't mean "10" it means "byte 10", in other words it's an address. I was too elated from getting it to work to slash my wrists over the stupidity.

So for those of you interested in how Konami coded their password generator (and subsequently the password verifier), have yourselves a peek.
Your mom has had more floppies put in her than a Commodore 64!


Follow my lack of progress on my game at my blog:
http://gmvania.blogspot.com

Offline TheouAegis

  • Amateur Auteur of GMvania
  • Master Hunter
  • *****
  • Posts: 1861
  • Gender: Male
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. The Great Defender will always defend the object of his or her fandom. Hack Master makes creations out of CV parts. (S)he makes Dr. Frankenstein proud.
    • GMvania Developer's Blog
    • Awards
  • Likes:
I'm kinda proud of this creation
« Reply #284 on: May 06, 2012, 09:33:30 PM »
0
Mind you, it's nowhere near the level of sophistication as anything Esco's put out, but for a newbie like me who never programmed anything beyond "LICK MY FUCKING NUTSACK!" in BASIC on the school's library computers, this is a very satisfying moment.

So this weekend I worked on the spinning trap doors found in the NES Castlevanias. You know, those ones that spin clockwise or counterclockwise depending on which side you land on and make you drop through, sometimes with spikes on the other side so you can't backtrack safely if you make one spin. THey might not seem that difficult, but the mechanics to them are tougher than scripting most of the enemies. An Axe Knight is a cakewalk compared to the spinny trap doors.

This is the code I came up with. The satisfying part is waaaaay down near the end dealing with spiked trap doors.

Code: [Select]
//Calling Script

if argument0.bbox_left>=sprite_get_bbox("bbox_right")-4 || argument0.bbox_right<=sprite_get_bbox("bbox_left")+4
    exit;

with argument0
    if obj_Belmont.x!=ceil(mean(sprite_get_bbox("bbox_left"),sprite_get_bbox("bbox_right")))
        if obj_Belmont.jump == 1
        {
            visible = 1;
            image_speed=1/12;
            image_xscale=sign(obj_Belmont.x-ceil(mean(sprite_get_bbox("bbox_left"),sprite_get_bbox("bbox_right"))));
            with obj_Belmont belmont_land();
        }

Code: [Select]
//Step Event in Trap Door object

var tile_L,tile_R;
tile_R=tile_layer_find(1000000,x,y);
tile_L=tile_layer_find(1000000,x-16,y);
if tile_L==tile_R
    tile_L=-1;

if (image_index==2/12 || image_index==5+2/12)
{
    tile_add(tile_get_background(tile_R),void_left,void_top,16,8,x,y,999998);
    tile_add(tile_get_background(tile_R),void_left,void_top,16,8,x-16,y,999998);
    if sprite_index == spr_trapspike
    {
        tile_add(tile_get_background(tile_R),void_left,void_top,16,8,x,y+8,999998);
        tile_add(tile_get_background(tile_R),void_left,void_top,16,8,x-16,y+8,999998);
    }
}   

if image_index==1 || image_index==6
{
    image_speed=1/11;
    if obj_Belmont.y==y && obj_Belmont.timeline_running=false
        obj_Belmont.y+=1;
}

if image_index==4 || image_index==9
    image_speed=1/12;

if (image_index==5 || image_index==0) && image_speed!=0
{
    tile_delete(tile_layer_find(999998,x,y));
    tile_delete(tile_layer_find(999998,x-16,y));
    if sprite_index = spr_trapspike
    {
        tile_delete(tile_layer_find(999998,x,y+8));
        tile_delete(tile_layer_find(999998,x-16,y+8));
        if image_index==0
        {
            tile_delete(tile_layer_find(999999,x,y+16));
            if tile_L
                tile_delete(tile_layer_find(999999,x-16,y+16));
        }
        else
        if image_index==5
        {
            tile_R=tile_add(tile_get_background(tile_R),tile_get_left(tile_R),tile_get_top(tile_R)+(y & 16)*dual_layer,tile_get_width(tile_R),16,tile_get_x(tile_R),tile_get_y(tile_R)+16+(y & 16),999999);
            tile_set_scale(tile_R,1,-1);
            if tile_L
            {
                tile_L=tile_add(tile_get_background(tile_L),tile_get_left(tile_L),tile_get_top(tile_L)+(y & 16)*dual_layer,tile_get_width(tile_L),16,tile_get_x(tile_L),tile_get_y(tile_L)+16+(y & 16),999999);
                tile_set_scale(tile_L,1,-1);
            }
        }
    }
    visible     = 0;
    image_speed = 0;
    image_xscale= 1;
    image_index = round(image_index);
}

Code: [Select]
//End Step in Trap Door object

//Handles collision of Belmont with spikes
if !obj_Belmont.hit
{
    if sprite_index==spr_trapspike && image_speed==0
    {
        if image_index==5
        {
            with obj_Belmont
            if sprite_get_bbox("bbox_left")<other.bbox_right && sprite_get_bbox("bbox_right")>other.bbox_left
            {
                if vspd>=0
                {
                    if y==other.y
                    {
                        enemy=other.id;
                        belmont_touch();
                    }
                }
            }
        }
        else
        {
            with obj_Belmont
            if sprite_get_bbox("bbox_left")<other.bbox_right && sprite_get_bbox("bbox_right")>other.bbox_left
            {
                if vspd<=0
                {
                    if sprite_get_bbox("bbox_top")<other.bbox_bottom && sprite_get_bbox("bbox_bottom")>other.bbox_bottom
                    {
                        enemy=other.id;
                        belmont_touch();
                    }
                }
            }   
        }
    }
}   


If you actually read all that, you probably noticed it uses 3 layers of tiles. The original in CV3 altered the background tiles, but you can easily edit the code to just keep the trap doors visible at all times. But if you want to stick with using tiles -- like me -- then you can bask in the awesomeness that is those lines with tile_add(). It works for both normal 16x16 tiles and 32x32 TSAs. ... Or at least I think it does. I tested it with TSAs.

Yes, I'm prouder of that than of my Crusher. Even though the Crusher is probably cooler (it uses draw_sprite_part() to draw the chain), it didn't use tiles like the source material. My spinny trap doors are close to the source and still useable in projects that don't actually rely on tiles (although why you wouldn't use tiles is beyond me since even Symphony of the Night can be recreated with tiles).
« Last Edit: May 06, 2012, 09:39:13 PM by TheouAegis »
Your mom has had more floppies put in her than a Commodore 64!


Follow my lack of progress on my game at my blog:
http://gmvania.blogspot.com

Tags: