Jump to content
IGNORED

Entry 2015: Slalom!


Recommended Posts

Back in February 2015, as my first experiment with IntyBASIC, I wrote a very simple slalom game. In honour of the competition and that there was nothing good on TV on a New Year's Eve, I decided to try to wrap it up with some scoring, lives and difficulty ramping. To most part it is tongue in cheek, and if nothing else an example of how easy it is produce smooth scrolling on the Intellivision.

 

slalom.bin

 

 

 

  REM Slalom
  REM by Anders Carlsson <anders.carlsson@sfks.se>
 
  REM 2015-02-15: Initial version
  REM 2015-12-31: Compo version
 
REM BACKGROUNDS
REM $0000 = BLACK    | $1000 = GREY     | $2000 = DA.GREEN | $3000 = CERISE
REM $0200 = BLUE     | $1200 = CYAN     | $2200 = MI.GREEN | $3200 = L.VIOLET
REM $0400 = RED      | $1400 = ORANGE   | $2400 = YELLOW   | $3400 = LI.GREEN
REM $0600 = L.YELLOW | $1600 = FO.GREEN | $2600 = WHITE    | $3600 = D.CERISE
 
REM FOREGROUNDS
REM $xx00 = BLACK    | $xx04 = DA.GREEN
REM $xx01 = BLUE     | $xx05 = MI.GREEN
REM $xx02 = RED      | $xx06 = YELLOW
REM $xx03 = L.YELLOW | $xx07 = WHITE
 
  REM  WAIT
  DEFINE 0,13,graph:WAIT
  DEFINE 13,5,graph2:MODE 1:WAIT
  score=0
 
title:
  BORDER 7,0:WAIT
  SPRITE 0,0,0,0
  CLS
  FOR i=1 TO 12:PRINT COLOR $2600,"                    ":NEXT
  PRINT AT 0 COLOR $2604,"\262\268\258\268  \257\265 \268  \262\268\258\265 \257\264\268"
  PRINT "\268\260\263\268  \262\267\258\268  \268\261\264\268\265\268\264\268"
  PRINT "\260\265 \268  \268\262\264\268  \268\261\264\268\260\261\264\268"
  PRINT "\259\261\264\268  \268\267\264\268  \268\261\264\268 \261\264\266"
  PRINT "\267\268\263\268\268\264\268\261\264\268\268\264\267\268\263\268 \261\264\268"
 
  PRINT AT 120,"ANDERS CARLSSON 2015"
  PRINT AT 160,"LAST SCORE: "
  PRINT <>score
  WAIT
 
waitbutton:
  IF CONT.BUTTON = 0 THEN GOTO waitbutton
 
  score=0
  life=3:misses=5
 
  BORDER 7,1:WAIT
 
  CLS
  FOR row=1 TO 11:PRINT AT row*20 COLOR $2600,"                    ":NEXT
 
  GOSUB draw_flags
  oy=0:od=0:port=0:score=0
  px=90:py=20
  #skier = $0878 : REM 00sc 1000 0111 1ccc
 
loop:
  IF oy=0 THEN od=4:oy=7 ELSE oy=oy-1
  SPRITE 0,$0300 + px,$0100 + py - oy,#skier
  SCROLL 0,oy,od:WAIT
  od=0:IF oy=7 THEN GOSUB clear_row
 
  IF CONT.LEFT AND px>0 THEN px=px-1:#skier=$0878
  IF CONT.RIGHT AND px<167 THEN px=px+1:#skier=$0880
 
  IF COL0 AND $0100 THEN GOSUB collision
  IF life>0 AND misses>0 THEN GOTO loop
 
  GOTO title
 
clear_row: PROCEDURE
  PRINT AT 11*20 COLOR $2600,"                    "
  port=port+1:IF port=6 THEN GOSUB draw_flags:port=0:GOTO no_trees
 
  IF RAND%3=0 THEN x1 = RAND%20:PRINT AT 11*20 + x1 COLOR $2604,"\269"
 
no_trees:
  RETURN
  END
 
draw_flags: PROCEDURE
  REM RAND is updated once per frame, so the subsequent calls will
  REM pretty much work like calling a variable, not a function
 
  x1=2 + RAND%7:x2=3 + RAND%3
 
  PRINT AT 11*20 COLOR $2607,"\273\273\273\273\273\273\273\273\273\273\273\273\273\273\273\273\273\273\273\273"
 
  PRINT AT 11*20 + x1 COLOR $2601,"\270"
  FOR i=1 TO x2:PRINT COLOR $2607,"\256":NEXT
  PRINT COLOR $2602,"\270"
 
  RETURN 
  END
 
collision: PROCEDURE
  REM check BACKTAB at $0200 and forward
 
  REM in foreground/background mode, STIC is oriented as follows:
  REM
  REM   13   12   11   10    9    8    7    6    5    4    3    2    1    0  
  REM +----+----+----+----+----+----+----+----+----+----+----+----+----+----+
  REM |BG  |BG  |GRAM|BG  |BG  |      GRAM/GROM Card #       |   FG Color   |
  REM |Bit2|Bit3|GROM|Bit1|Bit0|          (0 - 63)           |   Bits 0-2   |
  REM +----+----+----+----+----+----+----+----+----+----+----+----+----+----+
 
  REM bits 14-15 are unused by STIC and could be used to store information
 
  cx=(px-4)/8:cy=(py-4)/8
 
  REM cy will always be 2 (fixed at py=20)
 
  minx=cx-1:if minx<0 then minx=0
  maxx=cx+1:if maxx>19 then maxx=19
 
  REM nnbb rbbg gggg gccc
 
  #val=(PEEK(512+cx+cy*20) AND $09F8)/8
 
  REM PRINT AT 201 COLOR $2601,(#val/100%10+16)*8+6
 REM PRINT (#val/10%10+16)*8+6
  REM PRINT (#val%10+16)*8+6
 
  IF #val=256 THEN
     SOUND 0,100,10:FOR i=1 TO 5:WAIT:NEXT:SOUND 0,1,0
     score=score+1
  IF py<80 THEN py=py+4
  REM Don't remove slalom posts!
  WHILE (PEEK(512+minx+cy*20) AND $09F8)/8<>270:minx=minx-1:WEND
  WHILE (PEEK(512+maxx+cy*20) AND $09F8)/8<>270:maxx=maxx+1:WEND
  minx=minx+1:maxx=maxx-1
  ELSEIF #val=273 THEN
     PRINT AT 4 COLOR $2601,"MISSED PORT!"
  FOR i=1 TO 20:SOUND 0,600+i*20,10:WAIT:next
  SOUND 0,1,0:PRINT AT 4,"            ":misses=misses-1
  ELSE
     PRINT AT 5 COLOR $2601,"COLLISION!"
  FOR i=1 TO 20:SOUND 0,800+i*10,10:WAIT:next
  SOUND 0,1,0:PRINT AT 5,"          ":life=life-1
  END IF
 
  FOR i=cy-1 TO cy+1:FOR j=minx TO maxx:POKE 512+j+i*20,$2600:NEXT:NEXT
 
  RETURN
  END
 
graph:
REM 256 = between posts
  BITMAP "10101010"
  BITMAP "01010101"
  BITMAP "10101010"
  BITMAP "01010101"
  BITMAP "10101010"
  BITMAP "01010101"
  BITMAP "10101010"
  BITMAP "01010101"
 
  BITMAP "00000000"
  BITMAP "00000000"
  BITMAP "00000000"
  BITMAP "00000000"
  BITMAP "00001111"
  BITMAP "00001111"
  BITMAP "00001111"
  BITMAP "00001111"
 
  BITMAP "00000000"
  BITMAP "00000000"
  BITMAP "00000000"
  BITMAP "00000000"
  BITMAP "11110000"
  BITMAP "11110000"
  BITMAP "11110000"
  BITMAP "11110000"
 
  BITMAP "00000000"
  BITMAP "00000000"
  BITMAP "00000000"
  BITMAP "00000000"
  BITMAP "11111111"
  BITMAP "11111111"
  BITMAP "11111111"
  BITMAP "11111111"
 
  BITMAP "00001111"
  BITMAP "00001111"
  BITMAP "00001111"
  BITMAP "00001111"
  BITMAP "00000000"
  BITMAP "00000000"
  BITMAP "00000000"
  BITMAP "00000000"
 
  BITMAP "00001111"
  BITMAP "00001111"
  BITMAP "00001111"
  BITMAP "00001111"
  BITMAP "00001111"
  BITMAP "00001111"
  BITMAP "00001111"
  BITMAP "00001111"
 
  BITMAP "00001111"
  BITMAP "00001111"
  BITMAP "00001111"
  BITMAP "00001111"
  BITMAP "11111111"
  BITMAP "11111111"
  BITMAP "11111111"
  BITMAP "11111111"
 
  BITMAP "11110000"
  BITMAP "11110000"
  BITMAP "11110000"
  BITMAP "11110000"
  BITMAP "00000000"
  BITMAP "00000000"
  BITMAP "00000000"
  BITMAP "00000000"
 
  BITMAP "11110000"
  BITMAP "11110000"
  BITMAP "11110000"
  BITMAP "11110000"
  BITMAP "11110000"
  BITMAP "11110000"
  BITMAP "11110000"
  BITMAP "11110000"
 
  BITMAP "11110000"
  BITMAP "11110000"
  BITMAP "11110000"
  BITMAP "11110000"
  BITMAP "11111111"
  BITMAP "11111111"
  BITMAP "11111111"
  BITMAP "11111111"
 
  BITMAP "11111111"
  BITMAP "11111111"
  BITMAP "11111111"
  BITMAP "11111111"
  BITMAP "00000000"
  BITMAP "00000000"
  BITMAP "00000000"
  BITMAP "00000000"
 
  BITMAP "11111111"
  BITMAP "11111111"
  BITMAP "11111111"
  BITMAP "11111111"
  BITMAP "00001111"
  BITMAP "00001111"
  BITMAP "00001111"
  BITMAP "00001111"
 
  BITMAP "11111111"
  BITMAP "11111111"
  BITMAP "11111111"
  BITMAP "11111111"
  BITMAP "11111111"
  BITMAP "11111111"
  BITMAP "11111111"
  BITMAP "11111111"
 
graph2:
REM 269 = tree
  BITMAP "00011000"
  BITMAP "00111100"
  BITMAP "01111110"
  BITMAP "00111100"
  BITMAP "01111110"
  BITMAP "11111111"
  BITMAP "00011000"
  BITMAP "00011000"
 
REM 270 = post
  BITMAP "00011000"
  BITMAP "00111000"
  BITMAP "01111000"
  BITMAP "00011000"
  BITMAP "00011000"
  BITMAP "00011000"
  BITMAP "00011000"
  BITMAP "00011000"
 
REM 271-272 = skier
  BITMAP "00010000"
  BITMAP "00011000"
  BITMAP "11111111"
  BITMAP "00011000"
  BITMAP "00011001"
  BITMAP "01101110"
  BITMAP "10001000"
  BITMAP "00010000"
 
  BITMAP "00001000"
  BITMAP "00011000"
  BITMAP "11111111"
  BITMAP "00011000"
  BITMAP "10011000"
  BITMAP "01110110"
  BITMAP "00010001"
  BITMAP "00001000"
 
REM 273 = outside
  BITMAP "01010101"
  BITMAP "10101010"
  BITMAP "01010101"
  BITMAP "10101010"
  BITMAP "01010101"
  BITMAP "10101010"
  BITMAP "01010101"
  BITMAP "10101010"

  • Like 3
Link to comment
Share on other sites

Thanks! While I'm a relatively large fan of Morricone, this was a previously unknown piece to me. Actually, the first music that comes to my mind is "Pop Looks Bach" from the BBC TV programme Ski Sunday, which was reused in nearly every skiing computer game in the 1980s.

Link to comment
Share on other sites

Thanks, I forgot to add any screenshots. As mentioned, this was my first IntyBASIC experiment almost a year ago. It took me one evening to come up with the crude part of it, and then on New Year's Eve I added some more to make it game-like. Mostly considered a stocking filler, but if people like it, perhaps it can be improved.

 

Technically, perhaps the most interesting element in this game is how I use two GRAM cards (which probably could be GROM cards as well) that are painted white on white so they won't display on screen. One of those cards is drawn between the two posts to detect that you passed through a port successfully, the other card is drawn on both outer sides of the posts to detect that you missed a port. In all cases of collision, no matter the cause, there is an attempt to clear the area with real spaces so the collision won't happen right away. Sometimes this is less successful though. Perhaps the concept of using invisible characters to collide with to detect certain elements of gameplay is regularly used, but I thought it would be worth pointing out.

Link to comment
Share on other sites

Perhaps the concept of using invisible characters to collide with to detect certain elements of gameplay is regularly used, but I thought it would be worth pointing out.

I use a similar approach with my Mars Minis Descent game. I use 2 black, 1 pixel sized MOBs, either side of the landing platform (at the top) to detect if the lander's legs have made good contact. Works well and saves some computations.

Link to comment
Share on other sites

An observation I made that might be a red herring, is that at first I used the same pattern on both GRAM cards. Despite putting different cards into the BACKTAB, on collision it seemed to register as one and the same GRAM. Did I dream this, was it a programming mistake on my part or is the content of the screen determined by comparing pixel patterns vs ROM and RAM? It seems rather unlikely (though I know some computers like the ZX Spectrum does), but once I changed the pattern to something else, the program would work.

 

Normally you probably never would observe this as you don't define multiple GRAM cards with the exact same pattern, but I might try to reproduce this. Of course I'm only testing in jzintv but I have no reason to think it would be an emulator anomaly.

Link to comment
Share on other sites

An observation I made that might be a red herring, is that at first I used the same pattern on both GRAM cards. Despite putting different cards into the BACKTAB, on collision it seemed to register as one and the same GRAM. Did I dream this, was it a programming mistake on my part or is the content of the screen determined by comparing pixel patterns vs ROM and RAM? It seems rather unlikely (though I know some computers like the ZX Spectrum does), but once I changed the pattern to something else, the program would work.

 

I'm not sure what you mean by this. When you detect a collision you can only tell if a sprite hits a set pixel in a GRAM/GROM card by bitwise ANDing COLx with HIT_BACKGROUND. When that occurs you have to check between 1 and 4 BACKTAB cards surrounding the sprite in order to "see" what you hit (depends on your X and Y coordinate modulo 8 results).

Link to comment
Share on other sites

  • 3 weeks later...

Would it be possible to make a Parallel Slalom where you can race in a 2 player mode?

 

And of course you should rename the game to INGEMAR STENMARK SLALOM in honor of the greatest slalom skier of all time with 86 World Cup victories.
Also 5 times World Champion and 2 times Olympic Champion. (Between 1974 and 1989)

 

I remember that 2 of his main antagonists where US skiers Phil and Steve Mahre... ;-)

 

Anyways, I have looked for a Parallel Slalom computer game and have not found one.

In my own mind I think it could be really fun, a tense one-on-one competition.

 

Just a thought.

 

Gustavo Thoeni vs Ingemar Stenmark Parallel Slalom - Val Gardena 1975
(Of course in the only Parallel Slalom clip I could find he loses...)

 

1983 Aspen and Vail World Cup Races - Phil Mahre, Marc Ghiradelli and Ingemar Stenmark

(Yes, the Mahres do well in this clip)

 

Kyz3PKQ.jpg

Edited by NumbThumb
  • Like 1
Link to comment
Share on other sites

Heh. I don't know, it might turn into a Norwegian stop watch program (*) so one player can't go faster than the other remains on the screen.

 

Explanation: In the early 1980's, a Norwegian computer magazine published a stop watch program for the VIC-20. It had several advanced functions, like the ability to individually time multiple participants (runners etc) starting after eachother, and give their total times. The only caveat was that all participants must finish in the same order they started, i.e. you could not overtake an earlier starting opponent, then the stop watch wouldn't work. Since no race organizer would hold a race under those conditions, this part of the stop watch program was edited out when other magazines reprinted it.

Link to comment
Share on other sites

I suspected that there could be a similar thing to AUTO RACING where you cant get "out of screen" of your opponent.

If so, the game stops, you get a "AHEAD" if I remember correctly and get some extra points or extra time advantage.

And then you start again from where you were side by side. I do not remember exactly how it works but a similar thing could be applied here I guess.

 

Anyways, the game looks fun. A lot of potential. I can see more things to avoid such as pits and moving animals and rocks and stuff.

(Here I am thinking about "Alpiner" for the TI-994A. But the other way around, a free style skier trying to get down from the mountain...) ;-)

Link to comment
Share on other sites

I think having two vertical halves of the screen being drawn independently should be possible... I'm thinking if you created a course that's 10 tiles wide and however many tiles tall, you could use each player's y coordinate (relative to tiles tall) as an offset to draw the backgrounds for each player.

Link to comment
Share on other sites

Yeah, I was also thinking about a vertically split screen, but how would it cope with the smooth scroll unless both players race at the same speed? Of course in this very brief game that mostly was an exercise in learning how to use IntyBASIC scroll (and then make a little game around it), there is no speed factor at all.

 

Actually what would impress me is a conversion of a game like Mogul Maniac for the Intellivision, which I'm sure is possible for a talented programmer but probably not by me.

Link to comment
Share on other sites

Actually what would impress me is a conversion of a game like Mogul Maniac for the Intellivision, which I'm sure is possible for a talented programmer but probably not by me.

Using its sprite's multiple Y zoom factors and the X zoom factor the Inty could do a good version of that game. If you make the skis out of BACKTAB cards that would leave all 8 sprites for the flags. You could probably also have some eye candy trees if they were pre-drawn and pre-shifted at multiple sizes and copied into BACKTAB.

  • Like 1
Link to comment
Share on other sites

It seems I have a proof of concept code working for independent dual screen vertical scrolling!

 

Instead of scrolling the entire background, I decided to draw a flag that's 8 pixels tall, but draw it with two tiles (using 16 total tiles including 1 blank). This allowed me to repeatedly draw the flag tiles in the same 2 locations on screen and just switch what tile is being drawn, giving the illusion of 1 vertical pixel shift. When the flag reaches the top of the current tile row, I decremented the tile row by 20 and redrew the flag tiles again. This process is repeated from bottom to top so it appears the player is skiing down hill (I didn't draw a player but you'll get the idea). Just press 1 (fastest) to 9 (slowest) on each controller to set that player's speed. At the top middle of the screen is the current speed of each player and which player is moving faster.

 

Of course improvements need to be made to the code, but I'll leave that to anyone who wants to use it. And yes, it's free to use/modify/whatever you want to do with it. Enjoy!

 

dual_scrolling background.zip

  • Like 4
Link to comment
Share on other sites

It seems I have a proof of concept code working for independent dual screen vertical scrolling!

 

Instead of scrolling the entire background, I decided to draw a flag that's 8 pixels tall, but draw it with two tiles (using 16 total tiles including 1 blank). This allowed me to repeatedly draw the flag tiles in the same 2 locations on screen and just switch what tile is being drawn, giving the illusion of 1 vertical pixel shift. When the flag reaches the top of the current tile row, I decremented the tile row by 20 and redrew the flag tiles again. This process is repeated from bottom to top so it appears the player is skiing down hill (I didn't draw a player but you'll get the idea). Just press 1 (fastest) to 9 (slowest) on each controller to set that player's speed. At the top middle of the screen is the current speed of each player and which player is moving faster.

 

Of course improvements need to be made to the code, but I'll leave that to anyone who wants to use it. And yes, it's free to use/modify/whatever you want to do with it. Enjoy!

 

attachicon.gifdual_scrolling background.zip

 

That is pretty cool.

Link to comment
Share on other sites

It seems I have a proof of concept code working for independent dual screen vertical scrolling!

 

Instead of scrolling the entire background, I decided to draw a flag that's 8 pixels tall, but draw it with two tiles (using 16 total tiles including 1 blank). This allowed me to repeatedly draw the flag tiles in the same 2 locations on screen and just switch what tile is being drawn, giving the illusion of 1 vertical pixel shift. When the flag reaches the top of the current tile row, I decremented the tile row by 20 and redrew the flag tiles again. This process is repeated from bottom to top so it appears the player is skiing down hill (I didn't draw a player but you'll get the idea). Just press 1 (fastest) to 9 (slowest) on each controller to set that player's speed. At the top middle of the screen is the current speed of each player and which player is moving faster.

 

Of course improvements need to be made to the code, but I'll leave that to anyone who wants to use it. And yes, it's free to use/modify/whatever you want to do with it. Enjoy!

 

attachicon.gifdual_scrolling background.zip

Very similar technique to how this was done without MOBS:

[click to animate]

post-38229-0-58342200-1434863941_thumb.gif
Link to comment
Share on other sites

  • 5 weeks later...

The idea of having a dual screen scroller would be amazing. As a snowboarder, I would like to recommend a game where a skier on one side races or battles a snowboarder on the other side.

 

That would be cool! You could have collectables and set traps for the other player like in Crash Team Racing.

Link to comment
Share on other sites

That would be cool! You could have collectables and set traps for the other player like in Crash Team Racing.

Yes, traps. And maybe a few big jumps with a couple unique tricks for each player. Maybe even like the Olympic event, I think it is called boarder cross, where they race down the hill but there are obstacles, big turns, and some jumps. We played the original skiing game a lot as kids, but I don't like it as much as an adult. But, I think a ski/snowboarding game could be a lot of fun with some improved game play and with two player competition, esp. 2 player comp that doesn't rely on stopping the other player, like motocross.

Link to comment
Share on other sites

Note that Emerson's suggested method above involves predefining 16 GRAM cards for flags alone. I suppose a tree would be another 16 cards, some other obstacle 16 cards and then some animation of the skiers. Soon you have hit 64 cards, unless of course you can redefine cards on the fly during the VBLANK in order to conserve the total use of GRAM cards?

 

Display: Frame 1-2 (flags: 4 cards, trees: 4 cards, jumps: 4 cards etc). Define: Frame 3-4 (N * 4 cards)

Display: Frame 3-4. Redefine: Frame 5-6

Display: Frame 5-6. Redefine: Frame 7-8

Display: Frame 7-8. Redefine: Frame 1-2

 

This is however complicated by the fact that the two players may run at different speeds, so the scrolling can't be uniform - then we could just use hardware scroll as the original game. I understand in the scenario of having all frames predefined, this is not a problem except that it uses a lot of cards.

 

However this is not within my immediate plans, so if anyone likes to expand on my and Emerson's work, feel free to come up with a parallel slalom game.

Link to comment
Share on other sites

For the dingle player game just use hardware scrolling, and split GRAM cards into multiple player frames, a good selection of trees/rocks and a single flag,

For a two player game you are mostly focusing on what the other player is doing so you don't need different looking trees to spice up the display. In that mode I would have a single pre-shifted tree, a pre-sifted flag and use a couple of sprites on each player (maybe programmed on the fly) to have more colours.

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...
 Share

  • Recently Browsing   0 members

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