Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - dreamerman

#331
hm.. everyone may have  some preferences about such situations.. Some solutions:
1. Player can only climb up on ladders, every time he will press down key he will fall normally to lower platform, but if he is falling on ladder then there is no that stop/crouch after falling. So down key is like 'drop from current platform'.
2. Same movement as in current verision + if player is on a ladder that has nothing beneath it, he needs to press down again to fall from it - even if he is climbing down - something like double tap with key.

btw. nice effect with that falling burgers :)
#332
GLBasic is 'buy one time, get always free updates' software.
To be precise GLB creates win32 applications, so they will work on every windows, including Win 10, but it doesn't produces UWP app (won't work on Xbox/WinPhone).

Welcome back :)
#333
In such case, it all depends how fast enemies will move and so on, but thats good point, it's not Quake to do jump runs :D
That collisions are nice and efficient for gravity, with second layer (for bonuses / enemies) would be interesting approach in opossite to classic rect-based collision checking. This version and your description is sufficient, it could serve as solid tutorial on player movement. :)
#334
I have similar thoughts as bigsofty, if you are jumping and you land on same level platform there shouldn't be that stop / crouching. But overall movement is good.
btw. how you check for collisions? grabbing pixels from map or something hard-coded into game?
#335
Many years ago I've written an VB app to solve polynomials and draw graphs for them, key part of that project were routines for calculating simpler math stuff with keeping the proper order of performing mathematical operations. And that basically this code is, a simple math parser.
How to use it? First init with 'GOSUB math_parser_init', add your custom variables like 'x' with 'mp_add_iconst("x", 21)', and then just calculate with 'parse_math_cmd$(your_string$)' (you can also add custom functions) for example:
Code (glbasic) Select
GLOBAL user_str$, x_val$ // for inputed stuff
GOSUB math_parser_init

PRINT "Please type x value:", 10, 10
INPUT x_val$, 10, 20
mp_add_iconst("x", x_val$)
PRINT "Write equation below", 10, 30
INPUT user_str$, 10, 40
user_str$ = parse_math_cmd$(user_str$)
PRINT "result: " + user_str$, 10, 50
DEBUG "result: " + user_str$
SHOWSCREEN
MOUSEWAIT
END


You can use this for gui positioning/animations: button.left = integer(parse_math_cmd$("screen_width-20"))
or more advanced calculator app: result = parse_math_cmd$("2sin(0.5)+3(pi+int(1.1))-fps")
and so on...
#336
Also use GLB_ON_LOOP and all that stuff...
For now to set landscape/portrait I was using different resolutions in project options.. something like 9999x9998 for landscape, and reversed for portrait, tested on older OS versions, all was working fine..

One thing about device ID's, how is that PLATFORMINFO$(ID) generated? Currently on those systems there is so many id generating options for apps made with standard SDK's. Recommended way to generate random guid for android is:
Code (glbasic) Select
String uniqueID = UUID.randomUUID().toString();
There is also Advertising ID that can be used to track ads (similar thing is on WindowsPhone). I never used Android Extras in-app purchase code, how there particular device/user is recognized?

Such 'coding guide' would be great as sometimes it's hard to track little things that can cause problems on mobile devices. Even in form of forum topics..
#337
Generally if you don't need gui/window stuff you can write cmd/console application that will do same. If I understood correctly, your GLB app stars normally, then you activate (by click or whatever) calculation routines - those FOR based, and they took some time let's say 10seconds, in that time your app window is marked as 'not responding', and it's proper beheviour, remember if an application has a window it needs to proceed windows messages whole time, if it doesn't do that for particular time, it's marked as 'not responding', (VisualBasic there was easy solution for that - DoEvents() function, but GLB is different beast), after those loops end, application is again marked as normal as it handles windows messages on time. It's working same way in all languages.
Either use console app, or redesign your main loop: use LimitFps, put calculations to GLB_ON_LOOP sub and limit them so they would not take more than 1000/limitfps, and so on... Also maybe some optimizations in your loops could be done.
#338
Compiling for Win32 works ok, other platforms should also work as IDE reads 'platform.ini' files, but generally i test everything on windows. All information / features / issues you can find in mentioned topic, as I would prefer to keep all questions about it in one place :)
#339
If you would have other issues with setting style you can always change them directly in system registy 'current_user/software/Dream_Design/GLBasic/Color'..
Of course you can also check my alternative code editor that can be found here: https://www.glbasic.com/forum/index.php?topic=9531.0
;)
#340
OS it's not Series 30, but Series 30+, it doesn't support Java (J2ME), here is info: https://en.wikipedia.org/wiki/Series_30%2B
I don't even know if SDK for that platform is publicly available, so I doubt that there would be chance to add this target to GLB.. It would be better to check for Windows Phone 8.1/10 (Angle Project, UWP porting wizard)...
#341
GLBasic - en / Re: 2D camera
2017-Feb-22
Some tools do it through '2D emulation', as all scenes are 3D there and just camera is moved on X Y axis for normal movement, and on Z for zooming, yet it's some kind of slow from demos that I have checked some time ago so I think that they do some calculations in background.
As GLB is normal programming language not engine, you'r not bounded by some limitations imposed by engine itself..
Depending on your game, special effects that you want to use and so on, you have 3 options:
1. Viewport
2. OpenGL matrix transformations
3. Render to Texture / Offscreen
Currently I'm using option 2, and I'm prototyping with this little camera code:
Code (glbasic) Select

TYPE Point_2d
x%
y%
ENDTYPE
//2d camera type
TYPE game_camera_2d
    tile_size%          //domyslna wielkosc tile mapy
    tile_size_shifted%
    przes_mapy_px AS Point_2d       //MIN przesuniecie TO 0,0
    przes_mapy_tile AS Point_2d
    przes_mapy_czesciowe AS Point_2d
    visible_rect_px AS pg_rect      //faktycznie widoczny prostokat
    visible_rect_tiles AS pg_rect   //przeliczonyna tilesy
    zoom_current#                    //zoom kamery
    zoom_min#
    zoom_max#
    zoom_default#

    move_boundries AS Point_2d
    map_size_px AS Point_2d         //wielkosc mapy w px
    map_size_tiles AS Point_2d      //w tilesach
    camera_base_size AS Point_2d    //wielkosc canvasa na ktorym sie rysuje
    camera_curr_size AS Point_2d    //wielkosc aktualnego pola widzenia kamery
    camera_curr_tiled_size AS Point_2d  //wielkosc widzianego pola w tilesach

    //ustawia podstawowe dane kamery
    FUNCTION initCamera%: sizex%, sizey%, tile_size_xy%, map_width_px%, map_height_px%, boundries%
        LOCAL i1%, i2%
        self.tile_size% = tile_size_xy%
        IF (boundries% = 1)     //ustaw ograniczenie przesuwania
            self.move_boundries =  pg_return_p2d(tile_size_xy%, tile_size_xy%)
        ELSE
            self.move_boundries =  pg_return_p2d(0, 0)
        ENDIF
        self.przes_mapy_px = pg_return_p2d(self.move_boundries.x%, self.move_boundries.y%)
        self.camera_base_size = pg_return_p2d(sizex%, sizey%)
        //1,2,4,8,16,32,64,128,256 - sprawdzic czy poprawna wielkosc tile, wyliczyc shifted
        FOR i1% = 1 TO 8
            i2% = POW(2, i1%)
            IF (i2% >= self.tile_size%)
                self.tile_size% = i2%
                self.tile_size_shifted% = i1%

                BREAK

            ENDIF
        NEXT
        IF (map_width_px% >= 0)
            setMapSize_px(map_width_px%, map_height_px%)
        ELSE
            setMapSize_tiled(ABS(map_width_px%), ABS(map_height_px%))
        ENDIF
        setZoomMinMax(1.0, 5.0)
        calcMinZoom(0)
        setCameraZoom(1.0, 1)

        calcVisibleRect()
        //calc visibility

    ENDFUNCTION

    //ustawia wielkosc mapy w pikselach
    FUNCTION setMapSize_px%: width%, height%
        self.map_size_px = pg_return_p2d(width%, height%)
        self.map_size_tiles = pg_return_p2d(width% / self.tile_size%, height% / self.tile_size%)
    ENDFUNCTION

    //ustawia wielkosc mapy w tilesach
    FUNCTION setMapSize_tiled%: tilesx%, tilesy%
        self.map_size_px = pg_return_p2d(tilesx% * self.tile_size%, tilesy% * self.tile_size% )
        self.map_size_tiles = pg_return_p2d(tilesx%, tilesy%)
    ENDFUNCTION

    FUNCTION centerCameraOnP2D%: newx%, newy%
        //self.
    ENDFUNCTION

    //podstawowe poruszanie kamera, uwzgledania przeliczenia skali
    FUNCTION moveCameraByP2D%: movex%, movey%, scaled%
        IF (movex% = 0 AND movey% = 0) THEN RETURN 0
        IF (scaled% = 1)
            movex% = INTEGER(movex% / self.zoom_current#); movey% = INTEGER(movey% / self.zoom_current#)
        ENDIF
        LOCAL newx%, newy%
        newx% = self.przes_mapy_px.x% + movex%; newy% = self.przes_mapy_px.y% + movey%
        IF (newx% <> self.przes_mapy_px.x% OR newy% <> self.przes_mapy_px.y%)
            IF (newx% > (self.map_size_px.x% - self.camera_curr_size.x% - self.move_boundries.x%)); newx% = (self.map_size_px.x% - self.camera_curr_size.x% - self.move_boundries.x%); ENDIF
            IF (newx% < self.move_boundries.x%); newx% = self.move_boundries.x%; ENDIF
            IF (newy% > (self.map_size_px.y% - self.camera_curr_size.y% - self.move_boundries.y%)); newy% = (self.map_size_px.y% - self.camera_curr_size.y% - self.move_boundries.y%); ENDIF
            IF (newy% < self.move_boundries.y%); newy% = self.move_boundries.y%; ENDIF
            //jezeli pozycja sie zmienila to przeliczyc widoczny teren
            self.przes_mapy_px = pg_return_p2d(newx%, newy%)
            self.przes_mapy_tile = pg_return_p2d(ASR(newx%, self.tile_size_shifted%), ASR(newy%, self.tile_size_shifted%))
            self.przes_mapy_czesciowe = pg_return_p2d(MOD(newx%, self.tile_size%), MOD(newy%, self.tile_size%))
            calcVisibleRect()
        ELSE
            //nie bylo zmiany pozycji kamery, nie ma co przeliczac
        ENDIF
        RETURN 1
    ENDFUNCTION

    FUNCTION setCameraPos%: left%, top%
        //self.przes_mapy_px = pg_return_p2d(left%, top%)
        //IF (self.przes_mapy_px.x% < 0) THEN self.przes_mapy_px.x% = 0
        //IF (self.przes_mapy_px.y% < 0) THEN self.przes_mapy_px.y% = 0
        self.przes_mapy_px = pg_return_p2d(0, 0)
        self.moveCameraByP2D(left%, top%, 0)
        calcVisibleRect()
    ENDFUNCTION

    FUNCTION calcVisibleRect%:
        //rect_px.left = przes_x
        //right = left% + curr_size_x
        //

        self.visible_rect_px = pg_return_pgrect_pos(self.przes_mapy_px.x%, self.przes_mapy_px.y%, self.przes_mapy_px.x% + self.camera_curr_size.x% - 1, self.przes_mapy_px.y% + self.camera_curr_size.y% - 1)
        self.visible_rect_tiles = pg_return_pgrect_pos(ASR(self.visible_rect_px.left%, self.tile_size_shifted%), ASR(self.visible_rect_px.top%, self.tile_size_shifted%), ASR(self.visible_rect_px.right%, self.tile_size_shifted%), ASR(self.visible_rect_px.bottom%, self.tile_size_shifted%))
        self.camera_curr_tiled_size = pg_return_p2d(self.visible_rect_tiles.right% - self.visible_rect_tiles.left% + 1, self.visible_rect_tiles.bottom% - self.visible_rect_tiles.top% + 1)
        //myDEBUG("widzany rect tile: " + self.visible_rect_tiles.left% + "," + self.visible_rect_tiles.top% + "," + self.visible_rect_tiles.right% + "," + self.visible_rect_tiles.bottom%)

    ENDFUNCTION

    FUNCTION setZoomMinMax%: scale_min#, scale_max#
        self.zoom_min# = scale_min#; self.zoom_max# = scale_max#
    ENDFUNCTION

    FUNCTION zoomInOut%: value#, center_camera%
        //-(new_size_x -  old_sz) / 2
        LOCAL old_zoom# = self.zoom_current#, old_size AS Point_2d = self.camera_curr_size
        //LOCAL new_zoom# = self.zoom_current# + value#
        setCameraZoom(self.zoom_current# + value#, 1)
        IF (old_zoom# <> self.zoom_current#)
            //LOCAL old_size AS Point_2d = self.camera_curr_size
            //self.zoom_current# = new_zoom#
            //jezeli jest zmiana to przeliczyc pozycje / przesuniecie
            IF (center_camera% = 1)
                //ge_przesun_mape(-(self.camera_curr_size.x% - old_size.x%) / 2, -(self.camera_curr_size.y% - old_size.y%)/2)
                //moveCameraByP2D(-(self.camera_curr_size.x% - old_size.x%) / 2, -(self.camera_curr_size.y% - old_size.y%)/2, 0)

            ENDIF

        ENDIF
    ENDFUNCTION

    //ustawia przyblizenie kamery
    FUNCTION setCameraZoom%: value#, absolute%
        myDEBUG("---" + value# + ", absolute: " + absolute%)
        LOCAL scale_step# = 0.5     //scale_step# - dokladnosc przyblizenia skali
        IF (absolute% = 1)
            self.zoom_current# = value#
        ELSE    //ustalanie nowej skali z przyblizenia
            self.zoom_current# = 1.0
            WHILE (self.zoom_current# <= value#)
                INC self.zoom_current#, scale_step#
            WEND
        ENDIF

        IF (self.zoom_current# < self.zoom_min#); self.zoom_current# = self.zoom_min#; ENDIF
        IF (self.zoom_current# > self.zoom_max#); self.zoom_current# = self.zoom_max#; ENDIF

        IF (self.zoom_current# = 1.0)   //brak skalowania
            ge_skala_gry_spriteid% = -1
            self.camera_curr_size = pg_return_p2d(self.camera_base_size.x%, self.camera_base_size.y%)
        ELSE    //mamy skalowanie
            ge_skala_gry_spriteid% = 5
            self.camera_curr_size.x% = INTEGER(self.camera_base_size.x% / self.zoom_current#)
            self.camera_curr_size.y% = INTEGER(self.camera_base_size.y% / self.zoom_current#)
            //CREATESCREEN 5, ge_skala_gry_spriteid%, self.camera_curr_size.x%, self.camera_curr_size.y%
        ENDIF
        //IF (1 = 1) THEN self

        self.setCameraPos(self.przes_mapy_px.x%, self.przes_mapy_px.y%)
        //calcVisibleRect()
        //myDEBUG(GETTIMERALL() + "kreacja libacja")
        myDEBUG("--ustawiamy skale: " + self.zoom_current# + ", MIN/MAX skala: " + self.zoom_min# + "/" + self.zoom_max# + ", csize: " + self.camera_curr_size.x% + "x" + self.camera_curr_size.y%)
        //RETURN self.zoom_current#
    ENDFUNCTION

    FUNCTION calcMinZoom%: value%
        LOCAL min_skala#
        min_skala# = (pg_curr_resx% * 1.0) / self.map_size_px.x%
        myDEBUG(">>>" + pg_curr_resx% + ", map_width" + self.map_size_px.x%)
        IF (min_skala# < 1.0) THEN min_skala# = 1.0
        self.zoom_min# = 1.0
        WHILE (self.zoom_min# < min_skala#)
            INC self.zoom_min#, 0.5
        WEND

        myDEBUG("---MIN SKALA: " + self.zoom_min# + ", MIN val: " + min_skala#)

    ENDFUNCTION



ENDTYPE

Beware of  uncommented code, and all comments are in Polish, yet you can see how things are done..
To use this in you project:
Code (glbasic) Select
//define camera object
Global my_camera as game_camera_2d
//init camera - after preparing level/map
//canvas - size of camera draw destination, for single view games use screen size
//tile_size - size of your map tiles, mostly 16 or 32
//map size: >0 size in pixels, <0 size in tiles
//bounds - 0 or 1, use first & last maptiles as unpassable/drawable boundries
my_camera .initCamera(canvas_width, canvas_height, tile_size, map_width, map_height, bounds)
//below call with init camera on screen 800x600, with tiles size = 32, and map thats 128x32 in tiles.
//my_camera.initCamera(800, 600, 32, -128, -32, 1)
//zomm out
my_camera .zoomInOut(-1.0, 1)
//zoom in
my_camera .zoomInOut(1.0, 1)
//to move camera
my_camera .moveCameraByP2D(cx%, cy%, 0)
//set new map size
my_camera .setMapSize_tiled(size_x%, size_y%)
//for transformations with viewport / opengl use: my_camera.przes_mapy_px
//for calculationg what objects are visible - if you need that, use: my_camera.visible_rect.px


And as obvious, for larger projects, where you have hundreds of objects placed on large map, camera like this is proper way to deal with them (as you don't do all those calculations for draw position). For small games, even with scrolled maps but less objects it may not be needed.
#342
Update. Some little changes, generally fixes/optimizations. BinaryHeap code is much faster now (2-5 times in 10kk sorting elements scenario) yet difference is almost not notable with small open list for most maps. I don't know if there is chance to tweak code to get much better performance in pure GLB, of course for different maps other heuristic may be better, other cost values and so on, but that's 'default' values for normal maps. Real speed gain could be obtained with use of c++ inline, and normal arrays not vector class. But those functions should be sufficient for most scenarios. On small maps speed difference can be unnoticeable, but on real game maps you can easily see advantages of some  implementations (either speed, or better smoothed paths) so you have some variety of choice.

@Erico: Yeah, for proper human behaviour simulation path finding code should consider field of view and other restrictions, this could be nice demo app. But there is many issues with that, for example if some agent travels from A to B, he discovers some parts of map, does other agents see what map part were discovered, as from some point and many iterations / start-goal pairs most map would be discovered so depending on choosed implementation path would be similar to standard A*, or treat each path finding task as separate and map tiles should be always marked as undiscovered, and so on.. Many interesting ideas and things could be done with this, yet for most games simple path finding is sufficient, even today most games don't use 'discovered' flag for map tiles as units know from start what path is best, all to simplify/speedup searching, and make game more comfortable to player, so he don't need to select each way point manually.
It would be nice to see some complex path finding demo with many agents made in GLB.
#343
The issue with JPS is proper/optimal implementation, and this is real task, this algorithm is highly dependent on array reading/writing speed. Some GLB / C++ optimization expert would write this code better, with proper byref / alias / pointer usage, as I don't know where it would get most of it. I've looked at several JPS sources in JS/C++, but it's hard to determine how fast they really are as mostly they don't have proper testing routines on normal maps...
For example JPS+GoalBounding, everything looks nice, yet included maps are only 100x100, and output results times are strange, to compare with anything and it requires map preprocessing (analyzing that SC map that's included with my source was 4hours long and final file is 30MB :D). Other algorithms could be interesting, but many of them requires some map preprocessing, or significantly much more system memory for precomputed values.
It would be nice to be able to compare results from our routines with other codes. That's why added little benchmarking function, it's using *scen files (movingai.com / HOG2) so this is some kind standardized way to benchmark path finding functions (result printed as StdOut).

Nonetheless I did some changes in BinaryHeap, ALIAS used in few places and other simple optimizations, those are test with GLB generated 1000 pairs start-goal at medium-long distance on SC_map, times in seconds:
Code (glbasic) Select
previous - * - current version
350.0 - Classic - bugged
55.0 - Flood   - 24.0
25.0 - BH      - 15.6
  2.9 - Region  - 2.4
34.0 - JPS     - ~34.0

So there is still much to improve without inline stuff.
I've also added modified version of JPS - 4 way (horizontal + vertical movement) optimized for mazes (so also room maps) but can be used also on other maps, it requires a little preprocessing (it's fast as only calculate basic jump-stop points), and during run function is mostly doing simple checks like 'stop here?' no, ok jump to next tile. To test it, it's best to move only starting point, as target point need to be neighbor for some blocked tile, as this algorithm is mostly bouncing from walls.

It would be nice to see if anyone has some other path finding algorithm implementations, so we could do gather all of them in one place :-)
Attached project includes also previous version of functions, sorry for not polished code and ugly comments :]

ps. Oh yes DarkColony was  great game, sad that it wasn't so popular as other rts games from that time...
#344
I've added region based path finding, and very simple version of JPS (yet it isn't finished), generally all functions are useable, so you can compare them on different maps with few settings. That's good start if someone want's to write another custom path finding function.
Beside that there are some changes in main functions, like two variations of randomly generated terrain cost for loaded maps.
Of course in every implementation there is a place for additional optimizations, so results shouldn't be taken as final/definitive.
#345
Bug Reports / Re: v14 bugs ?
2017-Jan-25
Latest editor version was built with never compiler version but not all dll's are included in update package, there was some topic about this:
https://www.glbasic.com/forum/index.php?topic=10859.0