Jump to content
IGNORED

Grotto Escape


Bones-69

Recommended Posts

Rather than finish the last three programs I started, thought I might start something new after realising how well DISPLAY AT can be used in XB to get a reasonable large screen scroll. Below was my original test to see just how well it would work.

 

http://www.youtube.com/watch?v=Mlp516HJQ8w

Youtube has reduced overall quality and made it quite jumpy, however - when emulated it does run reasonably well with CPU Overdrive in Classic 99.

 

To use this technique I need to build an image with strings where each horizontal line is exactly 28 characters. The most characters that a single string can hold is 255. So by default the largest display area that I can potentially scroll in a single command is 9 rows x 28 columns (a total of 252 characters), which was the case in the above demo.

 

My new project named "Grotto Escape" will have a total resolution of 7056. Put another way, the game map will have 112 columns x 63 rows, OR (4 horizontal maps x 7 vertical maps).

blank-map.jpg

 

112 was chosen because it is evenly divisible by 28 and also 8. I want to horizontally scroll each screen with a buffer of 2 positions in either direction. 63 was chosen for similar reasons but in this instance it needed to be evenly divisible by the height (9 characters). Vertical scroll will have only a single character overlap on either side so it needed to be also divisible by 7, hence the magic number 63.

 

The array for the map will have 63 locations each filled with 112 characters which build the total map. This requirement alone will leave me with around 6400 remaining STACK which should be heaps of room for handful of other variables variables. This string will hold everything the player sees with the exception of sprites. It will also keep track of game events and all objects. For example, the players sprite might walk over a stick of dynamite and pick it up, when this happens the relevant line string and position is cut, a space inserted where the graphic for the dynamite was, and the balance of the string will be sown back together. There will be no need to manually keep track of of any item variables or their locations.

 

My idea for sprites in each location is a little different but still similar in principal.

 

In the strings themselves there will be the occasional character that is invisible to the player. When each 28 character string is fetched during the scroll process (triggered when the player moves towards the edge of the game field), a POS command will search each new 28 character string for the invisible character. If it finds the invisible character (lets call it the # character), it will calculate the row column position the # was found (by multiplying the row and column of the total map, and this number will refer to a single record on a disk file that contains a total of 7056 individual records. This record will be in the form of a positive or negative number such as -.1280700025 and from this number the program will identify which sprite character to display, the colour, the score for killing it, and other values that will set rules for the way the sprite behaves. If for example this sprite was an enemy and the player kills it, the original invisible character that was used to triggered the sprite event will be removed from the string location in the same way as described earlier, the next time this string is read the sprite trigger will not exist and no file will be looked-up. Seems simple enough..

 

Excluding the player, there will never exceed more than two enemy sprites on the screen at the same time, so game play should be quick and also the scroll process shouldn't be slowed because it will never fetch anymore than two disk files each time the screen is scrolled or re-drawn.

 

Now the game... I am shooting for some real nice sprite movement however CALL PATTERN will not be used - rather each character will have it's next animated step just redefined. Classic 99 with CPU throttling seems to do this without the flicker that usual TI speed produces.

 

http://www.youtube.com/watch?v=LNt-ZTR_oOg

 

Needless to say, this program is written with Classic Throttling in mind. It will never run on original hardware due to the graphics but more importantly due to the disc file size. SAVE GAME will be a feature of this game.

 

I have designed the player interface screens and am working on the initial two loaders. The first loader is to check the integrity of the big files and prepares the second loader to be run. The second loader defines the graphics and draws the screens. Almost all initialisation data from the game will be read from disc to save program space.

 

Here's hoping I get this one finished. Looking very forward to designing the maps. Magellan will be used extensively and the output converted to the strings which will then be saved to disc.

 

Magellan.jpg

 

Here are some sample game screens. Each screen won't be this "busy", but I have been trying to finalising the graphics and colours etc. I have been looking at these too long and lost my judgement - any feedback on the preferred colour scheme would be welcomed.

 

MS-yel-on-mag-black-check.jpg

 

MS-whiteonmgreenblackcheck.jpg

 

MS-cyanondarkblue.jpg

Link to comment
Share on other sites

Question Bones... when you're importing fonts to Magellan, do you have to do it tile by tile? That's always the sticker for me... It takes forever! =)

 

BTW, doing this for Classic99 OD as its primary plartform is something I've contemplated for a long time... It kind of ceases to be a TI game, but it's still awesome.

 

You should see the mess my Forest world .mag file is in... Yikes. =) I should just go through and re-do it from scratch to make it easier on myself, but I haven't been able to find the time or motivation. As it sits, it works... but I haven't got much room for much else like player SPRITEs.

Link to comment
Share on other sites

Question Bones... when you're importing fonts to Magellan, do you have to do it tile by tile? That's always the sticker for me... It takes forever! =)

 

BTW, doing this for Classic99 OD as its primary plartform is something I've contemplated for a long time... It kind of ceases to be a TI game, but it's still awesome.

 

You should see the mess my Forest world .mag file is in... Yikes. =) I should just go through and re-do it from scratch to make it easier on myself, but I haven't been able to find the time or motivation. As it sits, it works... but I haven't got much room for much else like player SPRITEs.

 

Classic99 OD isn't a panacea... It's still quite a challenge to get things to work. For example, my Inaccurate Invaders was still pretty slow in OD, and not that much better than regular. I'd suggest doing some testing to make sure your game plans are performant, before you build up an entire architecture that might not work.

Link to comment
Share on other sites

You know, that looks fantastic!

 

I'm flattered that you choose Classic99 as a platform, but seriously, if you get this done and want it to run on a real machine too, email me offlist (after it's done), and I will help you with the conversion to assembly. :) Maybe we can get a tool out of it.

Link to comment
Share on other sites

Very nice indeed! We haven't had any new platformer since Retrocouds' Pitfall remake... I wonder if it will run well on an accelerated console with the 3.58MHz crystal mod which supposed to give you a 20% speed boost. I have not done the modification myself, but it's on my list of things to do.

The save file you mentioned is obviously a real world obstacle, but maybe you could concatenate several "record" numbers into a single record and save quite a bit of space? The appropriate record could then be located through a combination of offsets based on the current character sprite position. The only issue here will be a bit of a slow down while calculating offsets and fetching the appropriate number.

One question I had as I was reading your game description was how you intended to insert invisible symbols in your strings and not have them mess up your display when putting them on screen using DISPLAY AT. Could you clarify this for me?

Link to comment
Share on other sites

One question I had as I was reading your game description was how you intended to insert invisible symbols in your strings and not have them mess up your display when putting them on screen using DISPLAY AT. Could you clarify this for me?

I have reserved character 33,34 & 35 which are all staying as blank characters ("0000000000000000"). I intended to put these into the strings and when encountered they could flag the specific action required. If I stick to keeping these on the common coloured back ground they remain invisible to the player, but I can still search for them using the POS command.

 

I am still deciding on how exactly I will use them to flag the action. My best choice is to simply look up the location from a disk record (this I like but it makes for large records which are 95% composed of nothing that will ever be used), or use the program to recognise the flag from the location and then jump somewhere else where it can load the variables. I am thinking of testing for both and seeing how the speed works out....

Link to comment
Share on other sites

Before going too far into designing maps and more sprites etc, I wanted to nail the way the game screen moved and see if the idea had any real limitations. I think I came have some fairly tidy code that moves the screen around probably about the best I had hoped for. In the actual game I don't expect this scroll speed to change much as there will only be a few additional enemy sprites being relocated as they scroll on or off the viewable area.

 

The current test map has some vertical and horizontal data on the top and left side. This was only to help me debug. The test map has 7056 locations (112 x 63) which is still currently my plan for the game resolution.

 

http://www.youtube.com/watch?v=cezf689xfnk

 

Would appreciate feedback on how it runs on different machines under full throttling (use arrow keys to move around). I can only test on a 4 year old Quad core and I do expect it to get a bit lazy on slower machines.

 

Scroll "engine" is lines 500 to 650.

 

 

100 DIM M$(63):: X=41 :: Y=41 :: T=1 :: N=1 :: C$="********"
110 CALL CLEAR :: CALL SCREEN(2):: FOR I=3 TO 13 :: CALL HCHAR(I,2,120,30):: NEXT I
120 CALL CHAR(97,"55803DBC3DBC01AA",104,"558019A4259801AA",120,RPT$("F",16))
130 CALL CHAR(128,"00000F080B0B0B0B0B0B0B0B0B0B080F0000FC04F4F4F4F4F4F4F4F4F4F404FC")
140 FOR I=1 TO 8 :: CALL COLOR(I,16,2):: NEXT I :: CALL COLOR(2,11,2,9,10,7,10,4,13,12,5,2)
150 A$=RPT$(RPT$("a",28)&RPT$("h",28),2):: B$=RPT$(RPT$("h",28)&RPT$("a",28),2)
160 FOR D=0 TO 63 STEP 18 :: FOR I=1 TO 9
170 M$(I+D)=A$ :: M$(I+9),M$(27+I),M$(45+I)=B$ :: NEXT I :: NEXT D
180 FOR D=9 TO 63 STEP 9 :: FOR I=1 TO 4 :: A=A+1 :: IF A<10 THEN A$="*MAP 0"&STR$(A)&"*" ELSE A$="*MAP "&STR$(A)&"*"
190 B$=SEG$(M$(D-4),1,I*28-18)&A$ :: M$(D-4)=B$&SEG$(M$(D-4),I*28-9,104)
200 B$=SEG$(M$(D-5),1,I*28-18)&C$ :: M$(D-5)=B$&SEG$(M$(D-5),I*28-9,104)
210 B$=SEG$(M$(D-3),1,I*28-18)&C$ :: M$(D-3)=B$&SEG$(M$(D-3),I*28-9,104):: NEXT I :: NEXT D
220 FOR I=1 TO 63 :: IF I<10 THEN M$(I)="0"&STR$(I)&M$(I)ELSE M$(I)=STR$(I)&M$(I)
230 NEXT I
235 A=65 :: M$(1)="01" :: FOR I=1 TO 112 :: :: M$(1)=M$(1)&CHR$(A):: A=A+1 :: IF A=91 THEN A=65
236 NEXT I ! M$(1) TEXT IS FOR TESTING. DEL 235 & 236
240 A$="" :: FOR I=0 TO 8 :: A$=A$&SEG$(M$(I+T),N,28):: NEXT I :: DISPLAY AT(4,1)BEEP:A$
250 CALL MAGNIFY(3):: CALL SPRITE(#1,128,16,Y,X)
260 GOSUB 1000 :: GOSUB 1010
269 ! USE CODE ONWARDS IN GAME
270 B=0 :: CALL KEY(0,K,A):: IF K=-1 THEN 270 ELSE IF K=13 THEN 270 ! USE ENTER TO TEST REMOVING MAP CHARACTER
280 IF K<8 OR K>11 THEN 270
290 IF K<10 THEN 340 !JUMP TO HORIZ MOVEMENT ELSE PROCESS VERT MOVEMENT
300 IF K=11 AND Y<32 THEN B=1 ELSE IF K=11 THEN Y=Y-1 ! IN GAME CHECK FOR GCHAR
310 IF K=10 AND Y>72 THEN B=1 ELSE IF K=10 THEN Y=Y+1 ! IN GAME CHECK FOR GCHAR
320 IF B<>0 THEN 400 !SPRITE HAS REACHED END OF SCREEN
330 CALL LOCATE(#1,Y,X):: GOSUB 1000 :: GOTO 270
340 IF K=8 AND X<30 THEN B=1 ELSE IF K=8 THEN X=X-1 ! IN GAME CHECK FOR GCHAR
350 IF K=9 AND X>210 THEN B=1 ELSE IF K=9 THEN X=X+1 ! IN GAME CHECK FOR GCHAR
360 GOTO 320
399 ! CHECK IF EDGES OF FULL MAP (63X112) HAVE BEEN REACHED
400 IF K=11 AND T=1 THEN 270 ELSE IF K=10 AND T=55 THEN 270
410 IF K=8 AND N<4 THEN 270 ELSE IF K=9 AND N>83 THEN 270
420 IF K<10 THEN 600
499 ! PROCESS VERTICLE
500 IF K=11 THEN T=T-2 :: A=MAX(T-4,1):: IF ABS(A-T)<>4 THEN A=A-1
510 IF K=10 THEN A=MIN(T+4,54)
520 IF A<T THEN B=-1 ELSE B=1
530 FOR D=T TO A STEP B :: A$="" :: FOR I=1 TO 9 :: A$=A$&SEG$(M$(D+I),N,28):: NEXT I :: Y=Y+-B*8
540 DISPLAY AT(4,1):A$ :: CALL LOCATE(#1,Y,X):: NEXT D :: T=D
545 IF K=11 THEN T=T+2
550 GOSUB 1000 :: GOSUB 1010 :: GOTO 270
600 C=-1 :: IF K=8 THEN A=MAX(N-22,1)
610 IF K=9 THEN A=MIN(N+22,86):: C=1
620 IF A<N THEN B=-1 ELSE B=1
630 FOR D=N TO A STEP B :: IF D+C=0 THEN 640
635 A$="" :: FOR I=0 TO 8 :: A$=A$&SEG$(M$(T+I),D+C,28):: NEXT I :: X=X+-B*8
640 DISPLAY AT(4,1):A$ :: CALL LOCATE(#1,Y,X):: NEXT D :: N=MAX(D,1)
650 GOSUB 1000 :: GOSUB 1010 :: GOTO 270
1000 DISPLAY AT(18,1):"SPRITE POS Y=";STR$(Y);"  X=";STR$(X):: RETURN
1010 DISPLAY AT(20,1):"STRING ROW=";STR$(T):"STRING POS=";STR$(N):: RETURN

Link to comment
Share on other sites

I have reserved character 33,34 & 35 which are all staying as blank characters ("0000000000000000"). I intended to put these into the strings and when encountered they could flag the specific action required. If I stick to keeping these on the common coloured back ground they remain invisible to the player, but I can still search for them using the POS command.

I see. Thanks :) BTW the scrolling looks great :)

Link to comment
Share on other sites

Thanks for trying it guys. The difference between systems is nice to know.

 

I have been playing around with some maps and I think one thing is now clear... Having a game screen height of just 9 characters makes it difficult for the little character to jump. Having the little dude jump was part of the original plan but I think I am going to have to ditch this, it just takes away from the game having to allocate jump clearance in the levels. I think now I am heading in a direction where the maze plays a bigger part of the game rather than "arcade action". Enemies will still exist but these must be destroyed to pass, rather than simply being able to jump over them.

Link to comment
Share on other sites

  • 2 weeks later...

Quick update for my new game.

 

Some changes to the original idea. Map has been changed to 45 x 120 (previously 63 x 112) as this allowed for more even scrolling and also gained another 1500 bytes memory which although I don't *think* I will need - it adds a nice buffer for the unforeseen and some extra bells and whistles.

 

After much consideration in regards to how I was going to trigger events for each new screen that scrolls into place, I came up with a pretty simple yet obvious idea. Although I can't define graphics ASCII characters over 143, I can put these characters into strings and display them and on the black screen background of the game - and they remain invisible to the player. In each new screen there will be the opportunity to use GCHAR to fetch the value of the character which controls the game events (this character will always appear in the same X/Y location in each screen). I can then use the value of this character within the program using ON GOTO or ON GOSUB to trigger events. Potentially this gives me 112 opportunities (characters 144 to 255) - even though I won't require this many, or for that matter have the programming space for this many events.... But using perhaps 50 doesn't seem unreasonable.

 

This works out really well as it now completely disolves the requirement of the massive disc files I thought I would have to originally use which were quite wasteful in the big scheme of things.

 

I am now in the process of building the level/s. Initially I hope to release the game with a single level (45 x 120 locations) and get some community feedback however the big plan is to build perhaps a game that consists of 5 levels each with a total grid of 45 X 120 locations. New levels will simply be read from disk so there is virtually no memory limitations in doing this.

 

At this stage I am experimenting with level design and attempting to learn what makes an interesting and fun level without the frustration of navigating these large maps. I am finding it is a fine line between making things too hard and frustrating, and making things to easy...

post-26079-0-82853700-1301876747_thumb.jpg

  • Like 2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...