I'm trying to create a system of moving the player by mouse, although not in the standard way. I am aiming for a method that is similar to the one used in games like XQuest (PC) and Crystal Quest (Mac) whereby you essentially control the player's inertia within a frictionless environment. Moving the mouse right would begin sliding the player in that direction until you moved left to come to a stop.
The basic code I have for this at the moment looks like this...
That code sort of works, but you have to move the mouse up-left a bit at the start to see the oval you're moving about. Also, because the mouse itself is unconstrained, when it hits the edge of the window, player control is lost, so there needs to be some way of resetting the mouse position cleanly without affecting the updates. If you uncomment the MoveMouse line within the main loop to do this, weirdness starts happening, and maybe I've just been looking at it too long today to see why... :(
Any advice gratefully received.
The basic code I have for this at the moment looks like this...
SuperStrict Framework BRL.GLMax2D Import BRL.FileSystem Import BRL.FreeTypeFont Import BRL.PNGLoader Import BRL.Retro 'Create graphics interface SetGraphicsDriver GLMax2DDriver() Graphics 800, 600 SetBlend ALPHABLEND SeedRnd MilliSecs() 'Types Global MEngine:XQ_MouseEngine 'Engine to control mouse movement of the player Global Player:XQ_Player 'The player ship 'Lists Global lstEntities:TList = New TList 'Types Type XQ_MouseEngine ' ---------------------------------------------------------------------------------- ' DESCRIPTION - Centralises all of the mouse-related functions into one engine. ' ---------------------------------------------------------------------------------- Field M1:Short, M2:Short 'Counter for mouse button actions Field tmx:Short, tmy:Short 'Mouse position on this tick Field pmx:Short, pmy:Short 'Mouse position on previous tick Field offx:Float, offy:Float 'Offset of last tick Field focx:Float, focy:Float 'Current X and Y movement focus Field sensitivity:Float 'How sensitive is movement? Method Destroy() Destroy() End Method Method Update() ' ----------------------------------------------------------------------------- ' DESCRIPTION - Every game tick, this function is called to compare the mouse's ' current position with it's last position. The values are used ' to manipulate the direction focus of the player. Also handles ' mouse click counters. ' ----------------------------------------------------------------------------- pmx = tmx pmy = tmy tmx = MouseX() tmy = MouseY() offx = (tmx - pmx) * sensitivity offy = (tmy - pmy) * sensitivity If MouseDown(1) Then M1 :+ 1 Else M1 = 0 If MouseDown(2) Then M2 :+ 1 Else M2 = 0 End Method Function Create:XQ_MouseEngine(sense:Float = 0.1) Local me:XQ_MouseEngine = New XQ_MouseEngine me.sensitivity = sense Return me End Function End Type Type XQ_Entity ' ---------------------------------------------------------------------------------- ' DESCRIPTION - All entities in the game - such as the player, the enemies and any ' and any bullets - as well some that don't move are created from this ' base type. ' ---------------------------------------------------------------------------------- Field x:Float 'X position Field y:Float 'Y position Field velx:Float 'X velocity Field vely:Float 'Y velocity Field ang! 'Angle Field speed! 'Directional speed Method New() lstEntities.AddLast Self End Method Method Destroy() lstEntities.Remove Self End Method Method Update() UpdatePositions() CheckCollisions() End Method Method UpdatePositions() x :+ velx y :+ vely End Method Method UpdateVelocities(ang!, speed!) velx = Sin(ang) * speed vely = Cos(ang) * speed End Method Method CheckCollisions() If x < 0 Or x > (GraphicsWidth() - 16) Then ang = 360 - ang If ang < 0 Then ang :+ 360 UpdateVelocities(ang, speed) EndIf If y < 0 Or y > (GraphicsHeight() - 16) Then ang = 180 - ang If ang < 0 Then ang :+ 360 UpdateVelocities(ang, speed) EndIf End Method Method Draw() DrawOval x-10, y-10, 20, 20 End Method Function UpdateAll() For Local e:XQ_Entity = EachIn lstEntities e.Update() e.Draw() Next End Function Function DestroyAll() For Local e:XQ_Entity = EachIn lstEntities e.Destroy() Next End Function End Type Type XQ_Player Extends XQ_Entity ' ---------------------------------------------------------------------------------- ' DESCRIPTION - The player entity. ' ---------------------------------------------------------------------------------- Function Create:XQ_Player(xpos:Short, ypos:Short) Local te:XQ_Player = New XQ_Player te.x = xpos te.y = ypos te.ang = 0 te.speed = 0 te.UpdateVelocities(te.ang, te.speed) Return te End Function End Type MEngine = XQ_MouseEngine.Create() Player = XQ_Player.Create(400, 300) 'Main program loop Repeat Cls MEngine.Update() DrawText "Entity count: " + lstEntities.Count(), 200, 10 DrawText "Offset X: " + MEngine.offx, 200, 25 DrawText "Offset Y: " + MEngine.offy, 200, 40 Player.velx :+ MEngine.offx Player.vely :+ MEngine.offy XQ_Entity.UpdateAll() 'MoveMouse 400, 300 Flip Until KeyDown(KEY_ESCAPE) XQ_Entity.DestroyAll() End
That code sort of works, but you have to move the mouse up-left a bit at the start to see the oval you're moving about. Also, because the mouse itself is unconstrained, when it hits the edge of the window, player control is lost, so there needs to be some way of resetting the mouse position cleanly without affecting the updates. If you uncomment the MoveMouse line within the main loop to do this, weirdness starts happening, and maybe I've just been looking at it too long today to see why... :(
Any advice gratefully received.