About Monkey 2 › Forums › Monkey 2 Programming Help › Raycast Solutions, does MX2 have anything like this?
This topic contains 5 replies, has 4 voices, and was last updated by
abakobo
11 months ago.
-
AuthorPosts
-
May 19, 2018 at 8:56 am #14658
Does MX2 have any raycasting functions and if not how would one go about coding one, both for 2d and 3d?
May 19, 2018 at 12:17 pm #14659Chipmunk has 2d raycasting, and also my own timelinefx has collisions with a raycasting function, there’s an example in the samples folder. Not sure about mojo3d but it uses bullet which must have raycasting functions built into it?
May 19, 2018 at 12:56 pm #14660Would I need to import chipmunk, timeline or bullet to access these? If so then, well, it would do what I need, but, I was hoping for a solution that was part of mojo that doesn’t need any extra imports.
May 22, 2018 at 1:39 am #14677For 2D I just use Bresenham Line on an array.
This is MX1 code but you should be able to convert it, it will return an int of a map array (eg the tile):
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172Method CheckCollision:Int(startX:Float, startY:Float, endX:Float, endY:Float)' use Bresenham LineLocal x1:Int = startXLocal y1:Int = startYLocal x2:Int = endXLocal y2:Int = endYLocal deltax:Int = Abs(x2 - x1)Local deltay:Int = Abs(y2 - y1)Local numpixels:Int, d:Int, dinc1:Int, dinc2:Int, xinc1:Int, xinc2:Int, yinc1:Int, yinc2:Int, x:Int, y:Int, i:IntLocal xx:Int, cx:IntLocal yy:Int, cy:IntLocal tile:IntIf deltax >= deltaynumpixels = deltax + 1d = (2 * deltay) - deltaxdinc1 = deltay Shl 1dinc2 = (deltay - deltax) Shl 1xinc1 = 1xinc2 = 1yinc1 = 0yinc2 = 1Elsenumpixels = deltay + 1d = (2 * deltax) - deltaydinc1 = deltax Shl 1dinc2 = (deltax - deltay) Shl 1xinc1 = 0xinc2 = 1yinc1 = 1yinc2 = 1EndIf x1 > x2xinc1 = -xinc1xinc2 = -xinc2EndIf y1 > y2yinc1 = -yinc1yinc2 = -yinc2Endx = x1y = y1For i = 1 To numpixelsxx = Floor(x / TILE_WIDTH)yy = Floor(y / TILE_HEIGHT)tile = map[yy][xx]' exit when we have a collisionIf tile <> 0 Thencx = xcy = yExitEndIf d < 0d = d + dinc1x = x + xinc1y = y + yinc1Elsed = d + dinc2x = x + xinc2y = y + yinc2EndNextReturn tileEndMay 22, 2018 at 2:48 am #14678Converted an old MX1 example:
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258Namespace myapp#Import "<std>"#Import "<mojo>"Using std..Using mojo..Const VIRTUAL_SIZE := New Vec2i(512, 256)Class RaycastWindow Extends WindowField player:PlayerField level:LevelMethod New()Super.New("Raycast", 640, 480, WindowFlags.Resizable)Layout = "letterbox"level = New Level()player = New Player(level)EndMethod OnRender(canvas:Canvas) OverrideApp.RequestRender()level.Draw(canvas)player.Draw(canvas)player.Update()EndMethod OnKeyEvent(event:KeyEvent) OverrideIf event.Type = EventType.KeyDown And event.Key = Key.Enter And event.Modifiers & Modifier.AltFullscreen = Not FullscreenEndifEndMethod OnMeasure:Vec2i() OverrideReturn VIRTUAL_SIZEEndEndClass PlayerField x:Float, y:FloatField dx:Float, dy:FloatField speedX:Float, speedY:FloatField width:Int, height:IntField level:LevelMethod New(level:Level)Self.x = level.playerXSelf.y = level.playerYSelf.level = levelspeedX = 4speedY = 5width = 16height = 16EndMethod Draw:Void(canvas:Canvas)canvas.Color = New Color(0, 255, 0)canvas.DrawRect(x - width / 2, y - height / 2, width, height)canvas.Color = New Color(255, 255, 255)EndMethod Update:Void()Local tempX:FloatLocal tempY:FloatIf Keyboard.KeyDown(Key.W)tempY = y - speedYIf level.CheckCollision(x, y - height / 2, x, tempY) = 0y = tempYEndElseif Keyboard.KeyDown(Key.S)tempY = y + speedYIf level.CheckCollision(x, y + height / 2, x, tempY) = 0y = tempYEndEndIf Keyboard.KeyDown(Key.D)tempX = x + speedXIf level.CheckCollision(x + width / 2, y, tempX, y) = 0x = tempXEndElseif Keyboard.KeyDown(Key.A)tempX = x - speedXIf level.CheckCollision(x - width / 2, y, tempX, y) = 0x = tempXEndEndEndEndClass LevelConst TILE_SIZE:Int = 16Field map:Tile[][]Field width:Int, height:IntField playerX:Int, playerY:IntField pixelWidth:Int = 0Field pixelHeight:Int = 0' 32 acrossGlobal level1:=New Int[](150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,124,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,124,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,124,0,0,0,0,0,0,0,0,0,0,0,0,0,150,150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,150,0,0,0,0,0,0,0,0,0,0,124,0,0,0,16,124,16,124,16,0,0,0,0,0,0,0,0,0,0,0,150,150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150)Method New()width = 32height = 16pixelWidth = width * TILE_SIZEpixelHeight = height * TILE_SIZEmap = TileArray(width, height)For Local x:Int = 0 To width - 1For Local y:Int = 0 To height - 1map[x][y] = New Tile((level1 [ x + y * width ] ))NextNextplayerX = 50playerY = 200EndMethod Draw:Void(canvas:Canvas)For Local x:Int = 0 To width - 1For Local y:Int= 0 To height - 1If map[x][y].frame > 0canvas.Color = New Color(map[x][y].red, map[x][y].green, map[x][y].blue)canvas.DrawRect(Int(x * TILE_SIZE), Int(y * TILE_SIZE), TILE_SIZE, TILE_SIZE)EndNextNextEndMethod CheckCollision:Int(startX:Float, startY:Float, endX:Float, endY:Float)Local x1:Int = startXLocal y1:Int = startYLocal x2:Int = endXLocal y2:Int = endYLocal deltax:Int = Abs(x2 - x1)Local deltay:Int = Abs(y2 - y1)Local numpixels:Int, d:Int, dinc1:Int, dinc2:Int, xinc1:Int, xinc2:Int, yinc1:Int, yinc2:Int, x:Int, y:Int, i:IntLocal xx:Int, cx:IntLocal yy:Int, cy:IntLocal tile:IntIf deltax >= deltaynumpixels = deltax + 1d = (2 * deltay) - deltaxdinc1 = deltay Shl 1dinc2 = (deltay - deltax) Shl 1xinc1 = 1xinc2 = 1yinc1 = 0yinc2 = 1Elsenumpixels = deltay + 1d = (2 * deltax) - deltaydinc1 = deltax Shl 1dinc2 = (deltax - deltay) Shl 1xinc1 = 0xinc2 = 1yinc1 = 1yinc2 = 1EndIf x1 > x2xinc1 = -xinc1xinc2 = -xinc2EndIf y1 > y2yinc1 = -yinc1yinc2 = -yinc2Endx = x1y = y1For i = 1 To numpixelstile = GetCollisionTile(x, y)' exit when we have a collisionIf tile <> 0 Thencx = xcy = yExitEndIf d < 0d = d + dinc1x = x + xinc1y = y + yinc1Elsed = d + dinc2x = x + xinc2y = y + yinc2EndNextReturn tileEndMethod GetCollisionTile:Int(x:Float, y:Float)If x < 0 Or x >= pixelWidth Or y < 0 Or y >= pixelHeight Then Return 0Local xx:Int = (Floor(x / TILE_SIZE))Local yy:Int = (Floor(y / TILE_SIZE))Return map[xx][yy].frameEndEndClass TileField frame:IntField red:Int, green:Int, blue:IntMethod New(frame:Int=0)Self.frame = framered = 255 - framegreen = 255 - frameblue = 255 - frameEndEndFunction TileArray:Tile[][](xSize:Int, ySize:Int)Local map:= New Tile[xSize][]For Local x:Int=0 Until xSizemap[x]=New Tile[ySize]NextReturn mapEndFunction Main()New AppInstanceNew RaycastWindowApp.Run()EndMay 22, 2018 at 6:10 am #14679you can do it with box2d too.
box2d is not in the form of a module now but it works fine.. the module should be there soonish.
just download the box2d fork and build these to see it working:https://github.com/abakobo/Box2D/blob/mx2/bananas/03-b2djson/e3-raycast_by_fixture.monkey2
https://github.com/abakobo/Box2D/blob/mx2/bananas/03-b2djson/e5-raycast_by_callback.monkey2Edit: you are looking for a non imort solution so therevils’ code should be better!
-
AuthorPosts
You must be logged in to reply to this topic.