![]() |
Forum Index : Microcontroller and PC projects : INKEY$ and multiple keypresses
Author | Message | ||||
karjo238 Regular Member ![]() Joined: 12/10/2018 Location: New ZealandPosts: 60 |
Hey there! My name is Joseph Karl, and after finding out about Geoff Grahams Colour Maximite, I'm reliving a wave of nostalgia, programming in BASIC the way I used to many, many years ago ![]() I have cut my teeth by making Super Star Trek work, which wasn't actually much work once you added spaces where necessary, and a real blast to play again. From there, I decided to boldly go into something of my own (sort of), which is a version of the Atari 2600 game Missile Command. I have done some work so far, and have had a great time making what I have done function, but I've come to an impasse. So, I'm in the business of finding help. I stumbled upon this forum, and thought, "Hey, this looks like the place!" My problem is that the game uses the arrow keys and the spacebar to move the cursor and fire the gun, but if I'm holding down more than one key, things don't function the way I expected. If I hold down the spacebar and then try and move the cursor, I can't. if I hold down the cursor keys and then press the spacebar, things work how I'd expect. I'm a newbie to this version of BASIC, and I'm probably doing something silly, but right now, I don't know what that is. This is the code. It needs cleaning up, I know, but it does mostly function. If anybody has any ideas, this somewhat clumsy coder would be glad to hear of it. Many thanks, Joseph :) Sub init x1 = 0 y1 = 0 x2 = 0 y2 = 0 sx = 240 sy = 400 outerRad = 30 innerRad = 20 adjac = 0 oppos = 0 hypo = 0 aimX = 200 aimY = 100 Dim shell1(5,5) LoadBMP"backg.bmp" Sprite Load "cross.spr" Sprite on 1,aimX,aimY mathstuff getpoints(angle, innerRad, outerRad) Line(x1,y1) - (x2,y2),7 main End Sub Sub fireshell q = 0 doneflag = false Pixel(x2,y2) = 0 Do If shell1(q,0) = 0 Then doneflag = true shell1(q,0) = x2 shell1(q,1) = y2 shell1(q,2) = aimX + 7 shell1(q,3) = aimY + 7 shell1(q,4) = x2 Else q = q + 1 EndIf Loop Until doneflag = true drawpoint End Sub Sub drawpoint For q = 0 To 4 If shell1(q,0) <> 0 Then x = shell1(q,4) Rem dx = endX - x2 dx = shell1(q,2) - shell1(q,0) Rem dy = endY - y2 dy = shell1(q,3) - shell1(q,1) y = shell1(q,1) + dy * (x - shell1(q,0)) / dx If y >= shell1(q,3) Then Pixel(x,y) = 7 If shell1(q,2) < shell1(q,0) Then shell1(q,4) = shell1(q,4) - 1 Else shell1(q,4) = shell1(q,4) + 1 EndIf Pixel(x,y) = 0 Else For j = 0 To 4:shell1(q,j) = 0:Next j EndIf EndIf Next q End Sub Sub getPoints (a,r,r1) x1 = sx + (r * Cos(a * Pi / 180)) y1 = sy + (r * Sin(a * Pi / 180)) x2 = sx + (r1 * Cos(a * Pi / 180)) y2 = sy + (r1 * Sin(a * Pi / 180)) End Sub Sub mathstuff oppos = sy - aimY adjac = Abs(sx - aimX) If adjac = 0 Then angle = 270 Else hypo = Sqr((oppos * oppos) + (adjac * adjac)) If aimX - sX > 0 Then angle = 360 - arcsin(oppos / hypo) * (180 / Pi) Else angle = 180 + arcsin(oppos / hypo) * (180 / Pi) EndIf EndIf End Sub Function arcsin(x) arcsin = Atn(x/Sqr(-x*x+1)) End Function Sub clearStuff Sprite off 1 Line(x1,y1) - (x2,y2),0 End Sub Sub drawStuff mathstuff getpoints(angle, innerRad, outerRad) Sprite on 1, aimX, aimY Line(x1,y1) - (x2,y2),7 End Sub Sub main Do While 1 = 1 a = KeyDown If a = 128 Then clearStuff aimY = aimY - 1 drawStuff drawpoint EndIf If a = 129 Then clearStuff aimY = aimY + 1 drawStuff drawpoint EndIf If a = 130 Then clearStuff aimX = aimX - 1 drawStuff drawpoint EndIf If a = 131 Then clearStuff aimX = aimX + 1 drawStuff drawpoint EndIf If a = 32 Then fireshell EndIf For t = 1 To 500:Next t Loop End Sub init |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
Welcome to the forum. I don't have a Maximite setup for testing. KeyDown is not a keyword in the current versions of MMBasic so it is difficult to test on a micromite (the Maximite successor). It also would depend on the keyboard routines so could not be easily tested using a terminal emulator. You could try a = asc(inkey$) and see if that is usable instead. Jim VK7JH MMedit |
||||
CaptainBoing![]() Guru ![]() Joined: 07/09/2016 Location: United KingdomPosts: 2170 |
Hey Joseph - you OK? A few questions: I haven't played with the MaxiMite, are you using a PS2 keyboard plugged directly in? Is KeyDown a Maximite (MMBasic) statement or a Sub you have written? With scanning a keyboard, if you have access to the hardware then you will be able to check for multiple (and multiple) keys pressed. If you are using a console connection then no such luck. If you hold a key down until it repeats then simultaneously hold another key down, the first input is abandoned in favour of the most recent. You can see this if you open an editor and hold a key down, then hold two keys down etc... thus you'll only ever see a single key with INKEY$ With the hardware in a keyboard, the state of the key up/down is sent by the keyboard controller (which may well be the system cpu) and the driver for it (which is a subsystem in the firmware) maintains a table of all the key number values. This gets updated as key states come in from the keyboard electronics and any tests for key states from (say your program) only ever has to go to the table (you don't actually do this, the system call does). You don't get this with a console connection because you are working through the driver on your PC etc which converts key presses to ASCII values - it is easier for most things to get the actual character of the key you pressed. The driver for the keyboard hides all this tedious state checking and stuff from you so your program can generally get on with the things you want to do... it can get in the way if you don't want that though. I think back to the days of my Amstrad 6128, you had INKEY$ which would fetch the character of he current key in the buffer (or "") and you also had INKEY(n) - note no $ - where n was the key number (in hardware) and the value returned would tell you if that key was up or down. All keys had a hardware number and could be checked - even keys that didn't produce any character - like CTRL and SHIFT. http://www.cpcwiki.eu/index.php/Locomotive_BASIC#INKEY_.28i.29. Some basics e.g. QBasic had an ON KEY(n) GOSUB event that worked by the key number. https://www.qbasic.net/en/reference/qb11/Statement/ON-KEY.htm So in short - if you have access to the key states coming from the keyboard electronics, you should be able to detect the state of individual keys. If you don't you might be stuck. |
||||
twofingers![]() Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1593 |
Hi Joseph, some idea (I did not test that): I would try to replace the SPACE with CTRL keypresses. (And maybe the CURSOR keys with w-a-s-z or similar if needed) Please take a look at the MMBasic manual for Maximites Appendix F Special Keyboard Keys. Normaly MMBasic interprets the keypresses as a serial stream. What you need - I think - is somethin more paralell working. Kind regards Michael EDIT: I had to edit for english keyboard layout. ![]() causality ≠ correlation ≠ coincidence |
||||
CircuitGizmos![]() Guru ![]() Joined: 08/09/2011 Location: United StatesPosts: 1427 |
Why not wire in your own buttons? You could use arcade buttons on the Maximite port and test for any combination of left, right, up, down, and fire states. Micromites and Maximites! - Beginning Maximite |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
KEYDOWN is a MMBasic function introduced in the Maximite to make game-playing easier. For rapid fire games, it is better than INKEY. The micromites were not considered a game platform so KEYDOWN was dropped, along with a lot of the graphic functions. Detecting multiple consecutive key-presses is going to be difficult. Using CTRL instead of SPACEBAR would work, but not when the CTRL/SPACE is the only key pressed. Having a game-pad with a few buttons wired up would be the most likely way to success. I am sure that someone would have done that in the past. Jim VK7JH MMedit |
||||
karjo238 Regular Member ![]() Joined: 12/10/2018 Location: New ZealandPosts: 60 |
Hey guys. Sorry for the delay in replying. Life(TM) gets in the way occasionally. The gamepad idea, now that you mention it, sounds like a great one. It would help lend an air of authenticity to what I'm trying to do here, so I'll have a hunt around and see what's available here in NZ, and see how difficult it is to hook up to the Maximite. Many thanks for your help thus far (I'm sure I'll have more questions in the future) Joseph ![]() |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2944 |
Hi Joseph, Welcome to the forum - and great that someone else is needing this feature. Even though it may not be what you are asking about; the way I overcame the issue (for 'GamePlay') was to use a Nintendo NunChuk. This is an I2C device so is easy to interface to via software, and gives a very nice direction/fire/jump type controller at a low cost. You can get 'Break-Out-Boards' that have the 6-pin connector shaped into a PCB with 0.1" headers. Google will help you locate availability for you; OR alternatively, you could cut off the end connector, and hard-wire the four relevant wires (two for power, and two for I2C). Rgds, WW |
||||
twofingers![]() Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1593 |
There is a Pacman clone (MAXMAN) in the MMBasic Library that maybe can be helpful. A NunChuk (clone from china at ebay) costs about 3.60 US$. causality ≠ correlation ≠ coincidence |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |