Page 22 of 23

Re: Tyhmät kysymykset (I/2012)

Posted: Thu Oct 17, 2013 10:07 pm
by Sly_Jack0
En kuollaksenikaan nyt osaa sanoa miksi, mutta tämä toimii:

Code: Select all

ObjectInteger ship_player\obj, ConvertToInteger(ConvertToType(ship_player))
En keksi, miten ship_player ei olisi jo valmiiksi tyyppimuuttuja. Enkä myöskään tiedä toimiiko ohjelma halutulla tavalla noin, se sinun pitää kertoa.

Re: Tyhmät kysymykset (I/2012)

Posted: Thu Oct 17, 2013 10:20 pm
by skorpioni-cb
Sly_Jack0 wrote:En kuollaksenikaan nyt osaa sanoa miksi, mutta tämä toimii:

Code: Select all

ObjectInteger ship_player\obj, ConvertToInteger(ConvertToType(ship_player))
En keksi, miten ship_player ei olisi jo valmiiksi tyyppimuuttuja. Enkä myöskään tiedä toimiiko ohjelma halutulla tavalla noin, se sinun pitää kertoa.
Toi toimi kääntämiseen, mutta ajon aikana siitä tuli errori "ConvertToType() failed! Could not find a converted type with ID 1" jotenkin minä arvasin että tämätyyppinen errori tulee hyvä yritys mutta...

Re: Tyhmät kysymykset (I/2012)

Posted: Thu Nov 14, 2013 6:42 pm
by MaGetzUb
Sly_Jack0 wrote:En kuollaksenikaan nyt osaa sanoa miksi, mutta tämä toimii:

Code: Select all

ObjectInteger ship_player\obj, ConvertToInteger(ConvertToType(ship_player))
En keksi, miten ship_player ei olisi jo valmiiksi tyyppimuuttuja. Enkä myöskään tiedä toimiiko ohjelma halutulla tavalla noin, se sinun pitää kertoa.
Uskoisin että pelkästään tämä riittää ongelman korjaamiseksi:

Code: Select all

ObjectInteger ship_player\obj, ConvertToInteger(ship_player)
Koska, ship_player on tyyppiosoitin, ja tyyppiosoittimenhan haluat muuttaa ConvertToIntegerillä kokonaisluvuksi. Kun taas haluat muuttaa kokonaisluvun tyyppiosoittimeksi, niin teet tuon ConvertToType():n. :) Eli koodissasi ei ole mitään järkeä, olet siis muuttamassa tyyppiosoitinta tyyppiosoittimeksi. ;)

Re: Tyhmät kysymykset (I/2012)

Posted: Thu Nov 14, 2013 8:15 pm
by Sly_Jack0
Alkuperäinen ongelmahan oli nimenomaan, että tuo postaamasi pätkä ei toimi.

Re: Tyhmät kysymykset (I/2012)

Posted: Thu Nov 14, 2013 11:46 pm
by MaGetzUb
Sly_Jack0 wrote:Alkuperäinen ongelmahan oli nimenomaan, että tuo postaamasi pätkä ei toimi.
Jahas, taisin jättää lukematta viestisi ja tehdä päätelmät ilman itse informaation ydintä.. (Tämmöisessä olen loistava xD) Tosiaan jännä, tuo jonka laitoin on ihan oikea tapa ja pitäisi toimia ilman mitään ongelmia. Et kai ole määrittänyt ship_player:ia ajemmin minään muuna muuttujana? Ja miksi edes käytät tuollaista ship_player tyyppiosoitinta...?

Re: Tyhmät kysymykset (I/2012)

Posted: Wed Dec 18, 2013 6:58 pm
by Ville
Taas kummastuttaa se miksi läppärilläni (900Mhz prosessori, integroitu näyttis, Windows XP) pelini toimii sujuvasti mutta pöytäkoneellani (Intel Core i7 2600K, Nvidia GeForce 570 Ti, Windows 7) pyörii puolella fps:llä..?

Code: Select all

SCREEN 1024,600,0,1
FrameLimit 60
Peli löytyy täältä: http://sdrv.ms/1fENlK8

Re: Tyhmät kysymykset (I/2012)

Posted: Thu Dec 19, 2013 6:32 pm
by Tikka19
Miten peliin voi tehdä lumisateen?
Jos vaikka päävalikossa sataisi lunta?
Anteeksi jos on liian tyhmä kysymys. :oops:

Re: Tyhmät kysymykset (I/2012)

Posted: Thu Dec 19, 2013 10:48 pm
by Ruuttu
Tikka19 wrote:Anteeksi jos on liian tyhmä kysymys.
Hehe, no vähä.

Yleensä kannattaa rajata se kysymys pienelle alueelle, vaikkapa "miten liikutan 100 objektia kerralla".
Kun pyydät valmista ratkaisua isoon ongelmaan, siitä ei välttämättä varsinaisesti opi mitään, eikä tarjottu toteutus välttämättä kuitenkaan kelpaa.

Code: Select all

SCREEN 800, 600
FrameLimit 60

// -----------------------

Function MakeRain(density# = 1, width = 0, height = 0)
    If width = 0 Then width = ScreenWidth()
    If height = 0 Then height = ScreenHeight()
    count = RoundUp(width * height * (density / 10000))

    main = MakeMEMBlock(count * 4 + 4)
    
    For drop = 0 To count - 1
        PokeShort main, drop * 4, Rand(width) * 21.0
        PokeShort main, drop * 4 + 2, Rand(height) * 21.0
    Next drop
    
    head = MakeMEMBlock(16)
    PokeInt main, count * 4, head
    
    PokeShort head, 0, count
    PokeShort head, 2, width
    PokeShort head, 4, height
    PokeShort head, 6, 0
    PokeShort head, 8, 32768
    
    Return main
EndFunction

Function DrawRain(rain, delta# = 16.666, rx = 0, ry = 0)
    
    size = MEMBlockSize(rain)
    head = PeekInt(rain, size - 4)
    
    lastdrop = (PeekShort(head, 0) + 0) -1
    t = PeekShort(head, 6)
    width = PeekShort(head, 2)
    height = PeekShort(head, 4)
    drift# = ((PeekShort(head, 8) + 0) - 32768) / 1000.0
    delta# = delta# / 16.666
    
    gravity# = 4.5
    
    For drop = 0 To lastdrop
        x# = (PeekShort(rain, drop * 4) + 0) / 21.0
        y# = (PeekShort(rain, drop * 4 + 2) + 0) / 21.0
        z# = 0.75 + ((drop Mod 11) ^ 1.66) * 0.025
        
        x# = x# + drift# * z# * delta# * (0.85 + Cos(t * 0.4 + (drop Mod 36) * 10) * 0.15)
        y# = y# + gravity# * z# * delta#
        If y > height
            y# = 0
            x# = Rand(width)
        Else
            If x > width Then x - width
            If x < 0 Then x + width
        EndIf
        
        PokeShort rain, drop * 4 + 2, y# * 21.0
        PokeShort rain, drop * 4, x# * 21.0

        Circle rx + x# - z#, ry + y# - z#, z# * 2
    Next drop
    
    PokeShort head, 6, t + delta# * 10
EndFunction

Function SetRainDrift(rain, x# = 0)
    head = PeekInt(rain, MEMBlockSize(rain) - 4)
    PokeShort head, 8, 32768 + x * 1000.0
EndFunction

// -----------------------

myRain = MakeRain(15)
SetRainDrift(myRain, 2)

Repeat

    DrawRain(myRain)
    Text 16, 16, "FPS: "+FPS()

DrawScreen
Forever

Re: Tyhmät kysymykset (I/2012)

Posted: Sat Mar 08, 2014 11:58 pm
by Hene

Code: Select all

oikea_vastaus$="la Date"
Ongelmani on, että CB pakottaa tiettyihin sanoihin (date, on, jne.) aina ison alkukirjaimen ja sekoittaa näin kaikki sellaiset ohjelmat, joissa kirjainkoolla on merkitystä. Pystyykö tuon estämään jotenkin?

Re: Tyhmät kysymykset (I/2012)

Posted: Sun Mar 09, 2014 12:10 am
by koodaaja
Purkkaratkaisuna käytin itse vastaavissa tilanteissa aina muotoa "jotain jotain d"+"ate" - ei nätti mutta toimii.

Re: Tyhmät kysymykset (I/2012)

Posted: Sun Mar 09, 2014 12:21 am
by Hene
Tuolla tosiaan ratkesi, kiitokset!

Re: Tyhmät kysymykset (I/2012)

Posted: Sun Mar 23, 2014 12:24 am
by aloittelijamies
Olen jo tähän etsinyt ja pohdiskellut vastausta, mutta ei onnaa!
Ongelmani liittyy kameran kääntämiseen/pyöräyttäiseen.Kääntämisellä/pyörittämisellä tarkoitan sitä, että pelimaailma näyttäisi esimerkiksi pyörivän johonkin tiettyyn suuntaan ilman, että objekteille tai kartoille tarvitsi tehdä erikoisempia muutoksia tai komentoja yms. Turncamera tai rotatecamera eivät vaikuta toimivan juuri tähän tarkoitukseen.

En osaa kamalan tarkasti selittää ongelmaani, mutta liitän pari kuvaa, josko niistä olisi apua selvennykseen.

Image
Image

Re: Tyhmät kysymykset (I/2012)

Posted: Sun Mar 23, 2014 12:41 am
by Latexi95
Muistaakseni CB:lle on tehty muutamia toteutuksia tästä, mutta en ihan suoraan löytänyt haulla koodinpätkää.

Toinen vaihtoehto on käyttää cbE:tä. Siinä muistaakseni RotateCameran ottama toinen parametri kääntää kameraa kokonaisuudessaan kuvailemallasi tavalla.

Re: Tyhmät kysymykset (I/2012)

Posted: Fri Apr 18, 2014 5:29 pm
by Kumiankka
Mikä mahtaisi olla vastine tälle CoolBasic:ssa

Code: Select all

z = x << y

Re: Tyhmät kysymykset (I/2012)

Posted: Fri Apr 18, 2014 6:49 pm
by Latexi95
Kumiankka wrote:Mikä mahtaisi olla vastine tälle CoolBasic:ssa

Code: Select all

z = x << y

Code: Select all

z = x Shl y

Re: Tyhmät kysymykset (I/2012)

Posted: Fri Jun 20, 2014 11:33 pm
by DJ-Filbe
Miten saan pyöritettyä 3d-maailmaa (kameraa) pysty/vaakasuunnassa niin, että voin kääntää kameran taaksepäin ja nähdä särmiöiden loittonevan kamerasta?

(Voit liikkua WASD ja nuolista)

Code: Select all

SCREEN 1000,700

Type vector
	Field x1
	Field y1
	Field z1
	Field x2
	Field y2
	Field z2
	Field cR
	Field cG
	Field cB
	
EndType


Function newVector(x1,y1,z1,x2,y2,z2,cR=255,cG=255,cB=255)
	v.vector = New(vector)
	v\x1=x1
	v\y1=y1
	v\z1=z1
	v\x2=x2
	v\y2=y2
	v\z2=z2
	v\cR=cR
	v\cG=cG
	v\cB=cB
EndFunction


camaX#=90.0
camaY#=0.0

sw=ScreenWidth()
sh=ScreenHeight()
sw2=ScreenWidth()/2
sh2=ScreenHeight()/2


For z=0 To 20
	For y=-1000 To 1000 Step 300
		For x=-1000 To 1000 Step 300
			
			cR=Rand(0,255)
			cRR=Rand(0,cR)
			cG=cRR*0.7
			cB=cRR*0.7
			rn=Rnd(0,0.2)
			newVector(x,y,z+rn,x+50,y,z+rn,cR,cG,cB)
			newVector(x+50,y+50,z+rn,x+50,y,z+rn,cR,cG,cB)
			newVector(x,y+50,z+rn,x+50,y+50,z+rn,cR,cG,cB)
			newVector(x,y,z+rn,x,y+50,z+rn,cR,cG,cB)
			
			newVector(x,y,z+0.5+rn,x+50,y,z+0.5+rn,cR,cG,cB)
			newVector(x+50,y+50,z+0.5+rn,x+50,y,z+0.5+rn,cR,cG,cB)
			newVector(x,y+50,z+0.5+rn,x+50,y+50,z+0.5+rn,cR,cG,cB)
			newVector(x,y,z+0.5+rn,x,y+50,z+0.5+rn,cR,cG,cB)
			
			newVector(x,y,z+rn,x,y,z+0.5+rn,cR,cG,cB)
			newVector(x+50,y+50,z+rn,x+50,y+50,z+0.5+rn,cR,cG,cB)
			newVector(x,y+50,z+rn,x,y+50,z+0.5+rn,cR,cG,cB)
			newVector(x+50,y,z+rn,x+50,y,z+0.5+rn,cR,cG,cB)
			
		Next x
	Next y
Next z







camZ#=2.0

camX#=0
camY#=0

Repeat
	
	camZ=camZ+(KeyDown(cbkeyW)-KeyDown(cbkeyS))*0.01
	
	camZ=camZ+0.5
	
	camaX=(camaX+((KeyDown(cbkeyRight)-KeyDown(cbkeyLeft))*1.5))
	camaY=(camaY+((KeyDown(cbkeyUP)-KeyDown(cbkeyDOWN))*1.1))
	
	camX=camX+(KeyDown(cbkeyD)-KeyDown(cbkeyA))*20
	
	camY=camY+(KeyDown(cbkeyW)-KeyDown(cbkeyS))*-Sin(camaY)*200
	
	For v.vector = Each vector
		If (v\z1-camZ) > 0 And (v\z2-camZ) > 0 Then
			x1=sw2*Cos(camaX)*4 + ((v\x1-camX)/(v\z1-camZ))+sw2
			y1=sh2*Sin(camaY)*4 + ((v\y1-camY)/(v\z1-camZ))+sh2
			x2=sw2*Cos(camaX)*4 + ((v\x2-camX)/(v\z2-camZ))+sw2
			y2=sh2*Sin(camaY)*4 + ((v\y2-camY)/(v\z2-camZ))+sh2
			intcol=v\cB+(v\cG Shr 8) + (v\cR shr 16)
			Color v\cR,v\cG,v\cB
			
			Line x1,y1,x2,y2
		ElseIf (camZ-v\z1) < 20 Then
			
			newVector(v\x1,v\y1,v\z1+20,v\x2,v\y2,v\z2+20,v\cR,v\cG,v\cB)
			Delete v
			
		EndIf
	Next v
	
	Color 255,255,255
	
	
	Text 0,0,"camaX="+camaX
	Text 0,20,"camaY="+camaY
	Text 0,40,"camZ="+camZ
	Text 0,60,"camX="+camX
	Text 0,80,"camY="+camY
	//SetWindow ""+FPS()
	
	DrawScreen
Forever


Re: Tyhmät kysymykset (I/2012)

Posted: Sun Jun 22, 2014 5:58 am
by MaGetzUb
DJ-Filbe wrote:Miten saan pyöritettyä 3d-maailmaa (kameraa) pysty/vaakasuunnassa niin, että voin kääntää kameran taaksepäin ja nähdä särmiöiden loittonevan kamerasta?

(Voit liikkua WASD ja nuolista)

Code: Select all

..da code..
Tästä voit lähteä soveltamaan jos kameran ei tarvitse katsoa suoraan alas tai ylös päin:
2D-avaruudessa pyöritys toimii näin:
x = cos(kulma) * x1 - sin(kulma) * y1
y = cos(kulma) * y1 + sin(kulma) * x1

:)

Tuo sinun Vector tyyppikokoelman oikeaoppinen nimi pitäisi olla Vertex. ;)
Vetexillä on taas attribuuteja esim 3-ulotteinen sijaintivektori ja esim 4-ulotteinen vektori joka sisältää esim. värin.
EDIT:

Aivan siis kuten atomimalli tarkensi, Vektorikokoelman nimi kannattaisi olla Lines tjsp. En allekirjoita kuitenkaan atomimallin verteksin ja vektorin eroa. :D Verteksi on verkeksi ja se koostuu erilaisista attribuutti vektoreista, kerran kyse on 3D-grafiikasta. :P

Tuota 2-ulotteista pyörittelyä ei voi hyödyntää monimutkaisempaan pyörittelyyn (esim kamera menee x-akselin ympäri ja maailma muuttuu ylösalaiseksi), koska siihen tarvitaan jo kvaternio matriisia.
Kannattaa tutustua Matriiseihin jos 3D kiinnosta. Matriisi on siis M x N kokoinen taulukko alkoita (niinkuin wikipediassa sanotaan), jotka pystyvät sisällyttää 3D objektin sijainnin, skaalauksen, vääntelyn ja asennon. Matriisilla voidaan siis kertoa toisia matriiseja ja vektoreita.

Kun olet matriisi tajunnut niin vektorin voit ajatella samanlaisena mutta vain 1-ulotteisena, M:n kokoisena taulukkona.

Tämäkin kannattaa katsoa jos 3D kiinnostaa.

Offtopikkia vielä:
"Kunnon" 3D:sä (mitä renderöidään Direct X:ä tai OpenGL:ä) käytetään on erilaisia matriiseja monikulmioiden rasterointiin:
View-matriisi, Model-matriisi ja Projektio-matriisi.

Kannattaa katsoa myös tämä video jos matriisi aihe kiinnostaa ja hard core:mpi 3D.

Re: Tyhmät kysymykset (I/2012)

Posted: Sun Jun 22, 2014 2:21 pm
by atomimalli
Linear mindsissä pyöritettiin vaan tolleen kun se riitti sopivaan kameraan. Sen koodi ei valitettavasti ole kovin esimerkillistä, joten koitan selittää vähän alla jotain.

Jos ei matriisit kiinnosta niin hyppää soveltaminen-osioon.

Matriisiselitysosa

Se on siinä ja siinä, olisiko demosta tullut nopeampi matriiseilla vai ei. Olisi ehkä säästänyt muutaman kertolaskun.

Matriisit mahdollistaisivat vapaamman kameran toiminnan ja myös muunlaisia muunnoksia kuin pyörityksen. Niitä ei kuitenkaan tarvinnut kun tiesi täysin, minkalaisista pyörityksistä ja liikutuksista kameran asennon halusi koostaa.

Matriiseista taitaa olla hyötyä lähinnä, jos ei tiedä, millaisista pyörityksistä lopullinen asento koostuisi, tai jos muunnos tarvitaan siirtää muualle kätevässä muodossa, kuten näytönohjaimilla.

Käsin tehtyjen pyöritysten kanssa voi tulla ongelmia joissain erikoisissa kuten suoraan ylös katsoessa. Siinä tulee apuun kvaterniot, joilla ei ole ongelmia eri suuntaisten pyöritysten kanssa ja joista sitten muunnetaan matriisi.

Matriisit ovat pohjimmiltaan vain yhdistettyjä muunnoksia, jotka tapahtuvat kerralla kertolaskussa. Aiemman viestin pyörityskaava vastaa täysin sitä, mitä pyöritysmatriisilla kertominen tekee vektorille:
http://en.wikipedia.org/wiki/Rotation_( ... dimensions
http://en.wikipedia.org/wiki/Transforma ... D_graphics

Grafiikassa on käytännössä väliä vain neliön muotoisilla matriiseilla. Kolmella ulottuvuudella tarvitaan 3x3 matriisia, mutta 4x4-matriiseihin saa mukaan vielä siirron ja projektion jotenkin käsittelemälllä viimeistä saraketta erilailla.
http://en.wikipedia.org/wiki/Transforma ... formations

Soveltaminen

Pyörityskaavaa sovelletaan niille kahdelle akselille, joiden muodostamalla tasolla halutaan pyöriä. Jos y on pystysuunta ja halutaan pyöriä vaakatasossa, valitaan pyöritettäviksi x ja z.
Pyöritys pitää tehdä siinä vaiheessa laskentaa, missä haluttu pyörityksen keskipiste on nollassa. Jos pyörityksen tekee ennen maailman siirtämistä, pyöritys tapahtuu maailman nollakohdan ympäri, eikä esimerkiksi pelaajan.

Tämän vuoksi DJ-Filben tulee jakaa ruudunkoordinaattien lasku(se missä viivat käydään läpi) useampaan osaan.
-Ensimmäisessä osassa tehdään liikutus

Code: Select all

uusix=x-camX
uusiy=y-camY
uusiz=z-camZ
-Toisessa osassa pyöritys tämän mukaan myötäpäivään.

Code: Select all

kulma=180 //täysikäännös
uudempix = cos(kulma) * x1 + sin(kulma) * z1
uudempiz = -sin(kulma) * x1 + cos(kulma) * z1
-Testataan, onko viiva kameran edessä (voisi hoitaa ehkä muullakin tavalla)

-Lasketaan uusista koordinaateista ruudun koordinaatit tutulla projektiokaavalla:

Code: Select all

ruudunx = zoomikerroin*uusix/uusiz+ruudunkeskix
ruuduny = zoomikerroin*uusiy/uusiz+ruudunkeskix

Muuta

Linear mindsissä viivat jaettiin lyhempiin viivoihin, jotta kalansilmäprojektio voisi tehdä niistä nättejä käyriä viivoja.(vaihdettu ylläoleva perspektiiviprojektio erilaiseen kaavaan, joka ei säilytä suoria linjoja ruudulla)
Tällöin siitä, että osa viivasta saattoi mennä kameran taakse, ei ollut hirveästi vaivaa. Pystyi poistamaan vain sen pienen pätkän viivaa.
Suorien viivojen tapauksessa näin ei kuitenkaan kannata tehdä. Riittäisi siirtää kameran tason takana oleva piste pikkiriikkisen verran sen tason etupuolelle. Tasan z=0 on huono, koska nollalla jakaminen ei toimi ja se sotkisi silloin projektiolaskun. Tätä raja-tasoa kutsutaan near-planeksi, jota lähempänä olevaa ei piirretä

Tästä tekee vaikean se, ettei riitä vain asettaa z=0.1, vaan uuden pisteen pitää osua alkuperäiselle viivalle. Se onnistuu varmaankin miettimällä ensin geometriaa vaikkapa paperilla ylhäältäpäin katsottuna(sivulta katsoen tapaus on samanlainen, joten riittää miettiä vaan toinen).
Kannattaa varmaankin piirtää suorakulmainen kolmio kameran takana olevan pisteen, z-planen ja viivan leikkauksen, sekä kohtisuoraan z-planella olevan viivan kanssa.
Kulmia ei kannata laskea, sillä se on ylimääräistä työtä. Pitäisi pärjätä keksimällä tilanteeseen sopivat kertoimet.

En ole koskaan jaksanut itse toteuttaa tätä. Aikanaan kokeilin tehdä tuota kolmiolle, mutta siinä tuli aivan liikaa tapauksia huomioitavaksi :S

Pienempiin viivoihin jakaminen mahdollistaisi kyllä sen, että viivat voi värittää tasaisemmin syvyyssuunnassa. Ehkä sitä kannattaa kokeilla.


Offtopic
Minun mielestäni kyseessä on viiva eikä vektori tai verteksi. Viiva koostuu kahdesta pisteestä. Vektori ja verteksi yhdestä.

Oikeastaan verteksillä ja vektorilla ei ole varsinaista eroa, sillä värikomponentitkin voidaan laskea vain lisäulottuvuuksiksi, jolloin olisi yhä kyseessä vektori. Vieläpä kahden päätepisteen tapauksessa.
Kuitenkin tämän vektorin on tarkoitus kuvata kahdeen pisteen muodostamaa viivaa, jolla on väri, joten sitä on järkevintä kutsua viivaksi.

Rasteroinnista voisi vielä mainita, että se on se vaihe, missä kaikki matriisit on jo käytetty ja koordinaatit ruudulla laskettu ja piirrellään pikseleitä. En tiedä miksikä sijaintien laskentaa kutsutaan. Kuitenkin nykygrafiikassa karkea jako on, että rasterointi rasterointi alkaa jossain verteksishaderin ja pikseli/fragmenttishaderin välissä.

Syy linear mindsin koodin sotkuisuuteen on se, että päätettiin olla käyttämättä funktioita, mikä nopeuttaa koodia, mutta tuo ongelmia parametrienvälitykseen varsinkin kun aliohjelmia käyttää sisäkkäin. Tästä syystä kamerakoodi piti kirjottaa neljästi, ettei viivan eri päiden muuttujat mene sekaisin keskenään. Toinen syy sen erikoisuuteen on varmaankin se, että käytimme cbpp:tä, joka mahdollistaa c-tyyliset makrot ja muuta kivaa. Pelottomimmille silmille koko koodi: mukana on myös yritys kääntää kamerakoodi makroiksi ja editorin koodi. Ensimmäiset yhdeksän parametrikäyrää kontrolloivat kameraa pyörityksillä ja siirroilla.

Jos nopeutta kaipaa niin Latexilta kannattaa kysellä coolbasic compilerista. Se oli demokunnossa jo viimeassyillä!

Re: Tyhmät kysymykset (I/2012)

Posted: Mon Sep 08, 2014 2:42 pm
by Paroni
Map.CB

Code: Select all

Type Map
	Field Name$
	Field Width%
	Field Height%
	' Layers
	Field BG1%
	Field BG2%
	Field OBJ%
	Field FG1%
	Field FG2%
EndType

Const BG1% = 0
Const BG2% = 1
Const OBJ% = 2
Const FG1% = 3
Const FG2% = 4

Function af_MakeLayer(Width%, Height%)
	_memSize% = ((Width * Height) Shl 2) + 4
	_lr% = MakeMEMBlock(_memSize)
	PokeShort _lr, 0, Width
	PokeShort _lr, 2, Height
	Return _lr
EndFunction

Function af_MakeMap(Name$, Width%, Height%)
	m.Map = New(Map)
	m\Name = Name
	m\Width = Width
	m\Height = Height
	' Layers
	m\BG1 = af_MakeLayer(m\Width, m\Height)
	m\BG2 = af_MakeLayer(m\Width, m\Height)
	m\OBJ = af_MakeLayer(m\Width, m\Height)
	m\FG1 = af_MakeLayer(m\Width, m\Height)
	m\FG2 = af_MakeLayer(m\Width, m\Height)
	Return ConvertToInteger(m)
EndFunction

Function af_LayerInsert(Handle%, X%, Y%, Value%)
	_width% = PeekShort(Handle, 0)
	_memSize = MEMBlockSize(Handle)
	' Calculate Position
	_y% = (_width * Y)
	_pos% = 4 + ((_y + X) Shl 2)
	' Make sure _pos is legal
	If _pos > _memSize Then Return False
	' Insert Value at Position
	PokeInt Handle, _pos, Value
EndFunction

Function af_MapInsert(Handle%, X%, Y%, Layer%, Value%)
	m.Map = ConvertToType(Handle)
	If Layer = BG1 Then
		af_LayerInsert(m\BG1, X, Y, Value)
	ElseIf Layer = BG2 Then
		af_LayerInsert(m\BG2, X, Y, Value)
	ElseIf Layer = OBJ Then
		af_LayerInsert(m\OBJ, X, Y, Value)
	ElseIf Layer = FG1 Then
		af_LayerInsert(m\FG1, X, Y, Value)
	ElseIf Layer = FG2 Then
		af_LayerInsert(m\FG2, X, Y, Value)
	EndIf
EndFunction

Function af_DrawLayer(Handle%)
	_width% = PeekShort(Handle, 0)
	_memSize% = MEMBlockSize(Handle)
	_i% = 4
	DRAW:
		_pos% = (_i Shr 2) - 1
		// Shl 3 = 8x8 tiles, Shl 4 = 16x16 tiles
		// Shl 5 = 32x32 tiles, Shl 6 = 64x64 tiles
		_x% = (_pos Mod _width) Shl 4
		_y% = (_pos / _width) Shl 4
		_val% = PeekInt(Handle, _i)
		Text _x, _y, _val
		If _val = 0 Then Goto UPDATE
		UPDATE:
		_i = (_i + 4)
		If _i = _memSize Then Return True
	Goto DRAW
EndFunction

Function af_DrawMap(Handle%)
	m.Map = ConvertToType(Handle)
	af_DrawLayer(m\BG1)
	af_DrawLayer(m\BG2)
	af_DrawLayer(m\OBJ)
	af_DrawLayer(m\FG1)
	af_DrawLayer(m\FG2)
EndFunction

Function af_DeleteMap(Handle%)
	m.Map = ConvertToType(Handle)
	DeleteMEMBlock m\BG1
	DeleteMEMBlock m\BG2
	DeleteMEMBlock m\OBJ
	DeleteMEMBlock m\FG1
	DeleteMEMBlock m\FG2
	Delete m
EndFunction

Main.CB

Code: Select all

Include "src/Sprite.CB"
Include "src/Map.CB"

grid_lr = af_MakeLayer(15, 10)
af_LayerInsert(grid_lr, 0, 0, 1)

andria = af_MakeMap("Andria", 15, 10)
'af_MapInsert(andria, 0, 0, FG2, 1)
'af_MapInsert(andria, 1, 1, FG2, 2)

MAIN:
	// [ Camera ]
	If LeftKey() Then MoveCamera -3, 0
	If RightKey() Then MoveCamera 3, 0
	If DownKey() Then MoveCamera 0, -3
	If UpKey() Then MoveCamera 0, 3
	
	SetWindow "" + FPS()
	DrawToWorld ON, ON, ON
		af_DrawLayer(grid_lr)
		'af_DrawMap(andria)
	DrawToWorld OFF, OFF, OFF
	DrawScreen
Goto MAIN
Ongelma on seuraavanlainen:
Jos (Main.CB:ssä) af_DrawMap(andria) on kommentoitu, puskee af_DrawLayer(grid_lr) MAVia. Tämä tapahtuu vain ja ainoastaan jos af_LayerInsert(grid_lr, 0, 0, 1) ei ole kommentoitu. Jos grid_lr:n sekä andrian layerit ovat tyhjiä, MAVia ei tule. Jos myöskin piirrän andrian, MAVia ei tule ja kaikki vaikuttaa pelittävän normaalisti.
Ajattelin, että DrawLayer menisi liian pitkälle muistissa, mutta ongelma ei ollut siinäkään.
Löytääkö joku koodista syyn sille miksi näin käy, vai onko tämä jokin CB:n bugi?

Testasin myös versiota, jossa piirretään kuvia tekstin sijaan eikä sama bugi toistunut siinä joten ongelmaa ei käytännössä ole, mutta en vain tahdo uskoa että vika olisi tekstinkirjoituksessa :|
(Toivon kylläkin niin)

Re: Tyhmät kysymykset (I/2012)

Posted: Wed Sep 10, 2014 3:07 am
by MaGetzUb
Koodi näyttää siistiltä eikä pitäisi virheille jäädä paljoakaan varaa. Mutta kuitenkin spottasin tällaisen pätkän piirtokoodista:

Code: Select all

..
Text _x, _y, _val
If _val = 0 Then Goto UPDATE
UPDATE:
..
Pitäisikö "if _ val = 0 Then Goto UPDATE" olla "Goto DRAW" koska nythän if _val =0 -ehdon täyttyessä, tämän alapuolella oleva koodi suoritetaan jokatapauksessa, täyttyykö ehto vai ei.