Valutazione 4.87/ 5 (100.00%) 5838 voti

Condividi:        

Giochino in Dev C++

Problemi di HTML? Di PHP, ASP, .NET, JSP, Perl, SQL, JavaScript, Visual Basic..?
Vuoi realizzare programmi in C, C++, Java, Ruby o Smalltalk, e non sai da che parte cominciare?
Entra qui e troverai le risposte!

Moderatori: Triumph Of Steel, archimede

Giochino in Dev C++

Postdi Paolo87 » 01/09/08 11:56

Ciao ragazzi e ben tornati dalle ferie per chi rientra oggi. Come sapete tempo fa iniziai a creare un giochino con questo splendito linguaggio di programmazione e dopo tanto ho quasi finito,ma come sempre accade per qualsiasi progetto personale,a volte viene accontonato e poi ripreso. Andando al sodo,io ho creato un array contente uno sprite con immagine bitmap e ripetuto per 5 volte,con movimento circolare da destra a sinistra rispettando la grandezza dello schermo e ricomparendo se esso arriva oltre lo schermo. Il problema mi è nato al cambio delle variabili del nemico e le funzioni che non vanno più,sono la collisione del player col nemico,il missile del player che colpisce il nemico e l osparo del nemico.Vi posto qui il codice commentato così possiamo capirci
Codice: Seleziona tutto
//librerie
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "allegro.h"
// immagini che formano le sprite
BITMAP *buf,*sprite,*sfondo,*scrolling,*cattivo,*playeresplode,*miss,*miss1,
*playeresplode1,*playeresplode2,*gv,*iniz;
// paletta dei colori
PALETTE colori;
// variaibli per lo scroll dello sfondo,direzione lancio missile,suoni vari  ed altro
int x,y,moltiplica,xscroll,xconto,yconto,morto,tempesplgioc,
fuoco,xmiss,ymiss,mortocattivo,tempesplcattivo,contapunti,vite,fine,suono1,
suono2,suono3,suono4,go,lancio=0,xpropal,ypropal,direzionex,direzioney,
proicont=0,lancio1=0,ini,meno;
// punteggio
char score[80];
//array del nemico,col numero di nemici e dv partono sullo schermo
int xa[100],ya[100],valorexa[100],valoreya[100],array, numeroa=10, start=100;
//suoni
SAMPLE *suono,*gameov;
MIDI *music;

void doppiobuffering()
// chiama il buff per non far saltare l'imm del gioco
{
vsync();
blit(buf, screen, 0, 0, 0, 0, 1024, 768);
clear(buf);
}

void inizio(){
//disegna im pre-gioco
if (ini==0) {         // variabile di inizio o di gioco: 0=inizio - 1=inizio //
draw_sprite(buf, iniz, 175, 175);
if (key[KEY_ENTER]) {
ini=1;
meno=0;
}
}
}

void nemico() {
//disegna nemico
if (ini==1)   {
for (array=0; array<=numeroa; array++)
{
draw_sprite(buf, cattivo, xa[array], ya[array]);
}
}
}

void movimento() {
//nemico si muove
if (ini==1) {
for (array=0; array<=numeroa; array++) {
xa[array]=xa[array]+1*valorexa[array];
ya[array]=ya[array]+1*valoreya[array];
if (xa[array]==576) valorexa[array]=-1;
if (xa[array]==0) valorexa[array]=+1;
if (ya[array]==438) valoreya[array]=-1;
if (ya[array]==0) valoreya[array]=+1;
}
}
}

void player() {
//giocatore sullo schermo
if (ini==1) { 
if (morto==1) {
draw_sprite(buf, sprite, x, y);
}
}
}

void movimentotasti() {
if (ini==1) { 
if (morto==1) {
if (key[KEY_LEFT]) x=x-2; if (x<=0) x=0;
if (key[KEY_RIGHT]) x=x+2; if (x>=883) x=883;
if (key[KEY_UP]) y=y-2; if (y<=0) y=0;
if (key[KEY_DOWN]) y=y+2; if (y>=690) y=690;
if (key[KEY_SPACE])
//variabile di missile giocatore
fuoco=1;                 
}
}
}

void fondale() {
if (ini==1) { 
xscroll=xscroll+3;;
blit(scrolling, buf, xscroll, 0, 0, 0, 1024, 768);
if (xscroll>1023) {
xscroll = 0;
}
}
}

void collisione() {
// collisione giocatore nemico
if (ini==1) {
if (((x+30)>=xa[array]) && (x<=(xa[array]+40))) {
if (((y+20)>=ya[array]) && (y<=(ya[array]+31))) {
morto=0;
}
}
}
}

void esplgioc() {
// il giocatore
if (ini==1) {
if (morto==0) {
if (tempesplgioc<=150) {
tempesplgioc++;
draw_sprite(buf, playeresplode2, x, y);
}
// se giocatore colpito riportalo alle variabili d'inizio e vite -1
else {
x=-10; y=280;
morto=1;
tempesplgioc=0;
vite--;
}
}
}
}

void missile() {
if (ini==1) {
if (fuoco==0) {
xmiss=x+75; ymiss=y-2;
}
if (fuoco==1) {
draw_sprite(buf, miss, xmiss, ymiss);
//xmiss++; //rimettere per un missile alla volta e togliere l'istruzione dopo
xmiss=xmiss+14; //+ missili se resta premuta la barra spaziatrice
if (suono2==0) {
play_sample(suono, 255,128,1000, FALSE);
suono2=1;
}
if (xmiss>=1024) {
fuoco=0;
suono2=0;
}
}
}
}

void cattivocolpito() {
if (ini==1) {
if (((xmiss+10)>=xa[array]) && (xmiss<=(xa[array]+40))) {
if (((ymiss+5)>=ya[array]) && (ymiss<=(ya[array]+31))) {
mortocattivo=0;
fuoco=0;
}
}
}
}

void esplcattivo() {
if (ini==1) {
if (mortocattivo==0) {
if (tempesplcattivo<=150) {
tempesplcattivo++;
draw_sprite(buf, playeresplode, xa[array], ya[array]);
}
else {
tempesplcattivo=0;
mortocattivo=1;
contapunti++;
}
}
}
}

void puntivite() {
if (ini==1) {
sprintf(score, "PUNTI: %ld VITE: %ld ", (long)contapunti, (long)vite);
textout(buf, font, score, 1, 1, 215);
}
}

void gameover() {
if (ini==1) {
if (vite==0) {
if (fine<=147) {
//textout(buf, font, "GAME OVER", 500,350, 215);
draw_sprite(buf, gv, 330, 350);
fine++;
if (suono3==0) {
play_sample(gameov, 255,128,1000, FALSE);
suono3=1;
}
}
else {
// riporto le variabili da zero se vite finite
tempesplgioc=0;
tempesplcattivo=0;
morto=1;
x=10; y=280;
yconto=3; xconto=0;
fuoco=0;
xmiss=0; ymiss=0;
mortocattivo=1;
contapunti=0;
vite=3;
fine=0;
go=1;
// variabili di suono attivate //
suono1=0; suono2=0; suono3=0, suono4=0;
xpropal = xa[array];
ypropal = ya[array];
}
}
}
}

void fuoconemico() {
if (ini==1) {
if (lancio==0){
proicont++;
if (proicont==76){
proicont=0;
lancio=1;
if (xa[array]>=x) direzionex=1;
if (xa[array]<=x) direzionex=2;
if (ya[array]>=y) direzioney=1;
if (ya[array]<=y) direzioney=2;
}
xpropal = xa[array]+1;
ypropal = ya[array]-1;
}
if (lancio==1) {
if (direzionex==1) xpropal=xpropal-3;
if (direzionex==2) xpropal=xpropal+3;
if (direzioney==1) ypropal=ypropal-3;
if (direzioney==2) ypropal=ypropal+3;
draw_sprite(buf,miss1, xpropal,ypropal);
if (xpropal<=0) lancio=0;
if (xpropal>=1024) lancio=0;
if (ypropal<=0) lancio=0;
if (ypropal>=768) lancio=0;
}
if (((xpropal+10)>=x) && (xpropal<=(x+80))) {
if (((ypropal+5)>=y) && (ypropal<=(y+51))) {
if (suono4==0) {
play_sample(gameov, 255,128,1000, FALSE);
suono4=1;
}
morto=0;
lancio=0;
suono4=0;
}
}
}
}

int main()
{
allegro_init();
install_keyboard();
set_color_depth(32);
set_palette(colori);
install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, 0);
suono = load_sample("fuoco.wav");
gameov = load_sample("gameover.wav");
set_volume(255,255);
set_gfx_mode(GFX_AUTODETECT, 1024, 768, 0, 0);
buf = create_bitmap(1024, 768);
clear(buf);
sprite = load_bmp("player.bmp",colori);
sfondo = load_bmp("fondone.bmp",colori);
cattivo = load_bmp("nemico.bmp",colori);
playeresplode = load_bmp("esplosione.bmp",colori);
playeresplode1 = load_bmp("esplosione.bmp",colori);
playeresplode2 = load_bmp("esplo.bmp",colori);
miss = load_bmp("missile.bmp",colori);
miss1 = load_bmp("missile1.bmp",colori);
gv = load_bmp("gv.bmp",colori);
iniz= load_bmp("iniz.bmp",colori);
scrolling = create_bitmap(2048, 768);
clear(scrolling);
for (moltiplica=0;moltiplica<=2048;moltiplica=moltiplica+1024) {
blit(sfondo, scrolling, 0, 0, moltiplica, 0, 1024, 768);
}
tempesplgioc=0;
tempesplcattivo=0;
morto=1;
x=10; y=280;
yconto=3; xconto=0;
fuoco=0;
xmiss=0; ymiss=0;
mortocattivo=1;
contapunti=0;
vite=3;
fine=0;
suono1=0; suono2=0; suono3=0, suono4=0;
play_midi(music, TRUE);
for (array=0; array<=numeroa; array++) {
start=start+60;
xa[array]=start; ya[array]=start;
valorexa[array]=1; valoreya[array]=1;
}
while (!key[KEY_ESC]) {
doppiobuffering();
fondale();
player();
player();
movimentotasti();
movimentotasti();
movimentotasti();
nemico();
movimento();
//fuoconemico();
collisione();
esplgioc();
missile();
missile();
cattivocolpito();
esplcattivo();
puntivite();
gameover();
inizio();
}
destroy_bitmap(buf);
destroy_bitmap(sprite);
destroy_bitmap(sfondo);
destroy_bitmap(cattivo);
destroy_bitmap(scrolling);
destroy_bitmap(playeresplode);
destroy_bitmap(playeresplode1);
destroy_bitmap(gv);
destroy_bitmap(iniz);
destroy_midi(music);
}
END_OF_MAIN ();
Paolo87
Utente Senior
 
Post: 305
Iscritto il: 26/08/07 09:54
Località: Roma

Sponsor
 

Re: Giochino in Dev C++

Postdi Dylan666 » 01/09/08 12:21

Sarebbe stato meglio se avessi continuato nell'altro topic. Almeno linkalo, altrimenti non si capisce quali cambiamenti hai fatto ;)
Avatar utente
Dylan666
Moderatore
 
Post: 38040
Iscritto il: 18/11/03 16:46

Re: Giochino in Dev C++

Postdi zello » 01/09/08 15:35

Quando ho un attimo magari ci guardo. Nel frattempo:
- quando si posta del codice, per pietà, cerchiamo di formattarlo decentemente. E' una pena leggere un sacco di roba non indentata, con delle parentesi che non si capisce dove si aprono e dove si chiudono
- quando parli di " funzioni che non vanno più", intendi che non compilano? Che non si comportano come dovrebbero? Che il computer prende fuoco? Se vuoi una risposta, cerca di documentare il più possibile le anomalie, senno' tocca verificare riga per riga e magari debuggando il codice (vedi anche nota sotto)
- Se includi librerie non standard, tipo allegro (#include "allegro.h", eh?), non dare per scontato che tutti le conoscano. Almeno dillo, che se per caso qualcuno vuole provare a compilare e debuggare sa cosa si deve procurare.
Il faut être toujours ivre. Tout est là : c'est l'unique question. Pour ne pas sentir l'horrible fardeau du Temps qui brise vos épaules et vous penche vers la terre,il faut vous enivrer sans trêve...
Avatar utente
zello
Moderatore
 
Post: 2351
Iscritto il: 06/05/02 13:44

Re: Giochino in Dev C++

Postdi Paolo87 » 01/09/08 17:33

Hai pienamente ragione e mi scuso non tanto ma tantissimo. Allora per sviluppare il gioco in dev c++ ho scaricato la libreria di allegro.h. Con tale libreria si possono fare dei giochi semplici,atti a conoscere le basi dello sviluppo di certe applicazioni. Per funzioni che non vanno,intendo che al momento della fase di running,non si comportano come dovrebbero e quindi non fanno quello che io ho pensato di fare. Per la storia dell'indentazione,beh hai ragione,ma credo che sia un fatto di abitudine,comunque mi impegnerò a farla per far capire a tutti coloro che leggeranno questo topic,il mio codice. se hai altre domande dimmi pure.
Paolo87
Utente Senior
 
Post: 305
Iscritto il: 26/08/07 09:54
Località: Roma

Re: Giochino in Dev C++

Postdi Paolo87 » 02/09/08 10:31

allora rivedendo la cosa mi sono accorto che se non mettevo un ciclo le cose non andavano. quindi nelle funzioni "cattivocolpito","fuoconemico","collisione" ci dovevo mettere dopo la prima istruzione if il seguente codice
Codice: Seleziona tutto
for (array=0; array<=numeroa; array++) {
ovvereo un ciclo for che caricava tutto il mio array di variabili. Ho fatto rigirare il progetto ma le cose non vanno come credevo (come sempre quindi),infatti le tre funzioni si comportano così :
1 - cattivocolpito = invece di disegnare l'imm della distruzione del nemico,dove è stato colpito la disegna in alto a sinistra sullo shermo ;

2 - fuoconemico = non fa nulla

detto ciò spero che mi aiutate a capire come fare per farle funzionare a dovere. Grazie mille per qualsiasi aiuto :)
Paolo87
Utente Senior
 
Post: 305
Iscritto il: 26/08/07 09:54
Località: Roma

Re: Giochino in Dev C++

Postdi zello » 07/09/08 21:56

allora rivedendo la cosa mi sono accorto che se non mettevo un ciclo le cose non andavano. quindi nelle funzioni "cattivocolpito","fuoconemico","collisione" ci dovevo mettere dopo la prima istruzione if il seguente codice

(naturalmente non mi ero accorto della tua risposta, e stavo per dire la stessa cosa...).
Tra l'altro, è una pessima abitudine usare una tonnellata di variabili globali, in particolare per gli iteratori di un ciclo (molto meglio definirli localmente).
2 - fuoconemico = non fa nulla

Ci credo, l'hai commentata via...
Codice: Seleziona tutto
//fuoconemico();

1 - cattivocolpito = invece di disegnare l'imm della distruzione del nemico,dove è stato colpito la disegna in alto a sinistra sullo shermo ;

E' sempre collegato ad un cattivo uso dei loop. Se in cattivocolpito scrivi codice come (ricordiamo che array è una var globale)
Codice: Seleziona tutto
void cattivocolpito()
{
  //tra l'altro, tutto questo verificare ini è inutile se scrivi il main in altra maniera,
  //e perdi solo tempo
  if(ini)
  {
    /*
    Due note sul loop: è sempre meglio il preincremento (++array) del postincremento (array++)
    per motivi di efficienza, e numeroa è una costante: in c++ l'avrei definita come
    const int numeroa=10, in c puoi ricorrere ad una #define del  preprocessore
    */
    for(array=0; array<=numeroa; ++array)
    {
      //accorpo i due if, ci sono comunque troppi "magic numbers" per i miei gusti
      if((xmiss+10)>=xa[array] && (xmiss<=(xa[array]+40)) &&
         (ymiss+5)>=ya[array] && (ymiss<=(ya[array]+31))
      {
         mortocattivo=0;
         fuoco=0;
      }
    }
  }
}

In pratica: se il tuo missile e uno dei tuoi nemici sono piuttosto prossimi, segnali che il nemico salta per aria e che il proiettile deve sparire. Poi, nella funzione eslpcattivo "dipingi" l'esplosione, usando xa[array] e ya[array] come coordinate. L'unico problema è che il ciclo sopra non finisce: continua fino a che array non è maggiore di numeroa. Quando chiami esplcattivo xa[array] e ya[array] puntano oltre il termine dell'array, e ti va già grassa di ottenere un 0,0 (cioé le coordinate di angolo), perché un bel crash sarebbe infinitamente più probabile.
Il faut être toujours ivre. Tout est là : c'est l'unique question. Pour ne pas sentir l'horrible fardeau du Temps qui brise vos épaules et vous penche vers la terre,il faut vous enivrer sans trêve...
Avatar utente
zello
Moderatore
 
Post: 2351
Iscritto il: 06/05/02 13:44

Re: Giochino in Dev C++

Postdi Paolo87 » 08/09/08 06:57

Grazie per la dritta, ;) ,ma nonostante ci sia arrivato pure io a quel dannato ciclo che non finisce nel modo corretto,non sono riuscito a capire come farlo terminare nel modo corretto.
Paolo87
Utente Senior
 
Post: 305
Iscritto il: 26/08/07 09:54
Località: Roma

Re: Giochino in Dev C++

Postdi zello » 08/09/08 07:44

Premettendo che:
- io riscriverei tutto da capo, sfruttando di più le variabili locali, la possibilità di passare argomenti alle funzioni (e di ritornare valori), magari leggendo qualcosa di programmazione funzionale (non necessariamente relativo al C).
- non ho compilato e debuggato, ho tirato solo un occhio alle funzioni che mi hai indicato. Ho una visione del codice molto approssimativa.

se il problema è - come penso - che cattivocolpito deve individuare se c'è un cattivo colpito, e se è così lasciare in array l'indice delle coordinate dell'esplosione e in mortocattivo un flag se l'esplosione è da disegnare (tra l'altro, perché un flag invertito? Non sarebbe meglio 1 per segnalare che il proiettile ha colpito qualcosa, e 0 se non ha colpito nulla?), allora è necessario uscire dal loop non appena rilevi la collisione. Beh, questo è semplice.
Codice: Seleziona tutto
 {
         mortocattivo=0;
         fuoco=0;
         break;
 }

L'istruzione break esce da un ciclo (for oppure switch oppure while), e l'esecuzione continua all'istruzione successiva al ciclo.
Codice: Seleziona tutto
int i=0;
//ciclo infinito
for (;;)
{
     if((++i)>10)
         break;
}
printf("%d\n",i); //stampa 11
Il faut être toujours ivre. Tout est là : c'est l'unique question. Pour ne pas sentir l'horrible fardeau du Temps qui brise vos épaules et vous penche vers la terre,il faut vous enivrer sans trêve...
Avatar utente
zello
Moderatore
 
Post: 2351
Iscritto il: 06/05/02 13:44

Re: Giochino in Dev C++

Postdi Paolo87 » 08/09/08 08:04

Perchè non ci avevo pensato al break ?! Devi sapere che per certe cose prendo sempre la strada più lunga anzichè quella più breve :o . Però mi viene inmente subito una cosa,usando il break non solo nella funzione "cattivocolpito",ma anche nella funzione "esplcattivo",poi il programma non disegna l'immagine dell'esplosione del nemico sempre nello stesso punto?! Cioè,se io colpisco il primo nemico dell'array,il nemico che esplode non è sempre il primo o l'ultimo ?! Poi altra cosa che mi sono accorto,(ora la provo ma non sono sicuro),nell'ultima parte del codice :

Codice: Seleziona tutto
destroy_bitmap(buf);
destroy_bitmap(sprite);
destroy_bitmap(sfondo);
destroy_bitmap(cattivo);
destroy_bitmap(scrolling);
destroy_bitmap(playeresplode);//distrugge l'immagine del nemico colpito
destroy_bitmap(playeresplode2);
destroy_bitmap(gv);
destroy_bitmap(iniz);
destroy_midi(music);
}
END_OF_MAIN ();

dove distruggo le bitmap per non occupare spazio una volta terminata una funzione,credi che devo mettere un ciclo pure nella distruzione della " bitmap playeresplode " ?!
Paolo87
Utente Senior
 
Post: 305
Iscritto il: 26/08/07 09:54
Località: Roma

Re: Giochino in Dev C++

Postdi Paolo87 » 08/09/08 08:16

scusa non li,ho sbagliato,magari il punto esatto non è nel bitmap ma :

Codice: Seleziona tutto
destroy_bitmap(cattivo);
}


Diventando così =>
Codice: Seleziona tutto
for (array=0; array<=numeroa; array++) {
destroy_bitmap(cattivo);
}
Paolo87
Utente Senior
 
Post: 305
Iscritto il: 26/08/07 09:54
Località: Roma

Re: Giochino in Dev C++

Postdi zello » 08/09/08 11:13

Codice: Seleziona tutto
for (array=0; array<=numeroa; array++) {
destroy_bitmap(cattivo);
}

No. Così distruggi 10 volte la stessa bitmap (cosa inutile, e il cui risultato dipende strettamente dalle precondizioni della funzione destroy_bitmap di allegro, ma che molto probabilmente scatena un undefined behaviour).
Per ciò che riguarda esplcattivo, vediamo un po' il codice
Codice: Seleziona tutto
void esplcattivo() {
if (ini==1) {
   if (mortocattivo==0) {
      if (tempesplcattivo<=150) {
         tempesplcattivo++;
         draw_sprite(buf, playeresplode, xa[array], ya[array]);
         }
      else {
         tempesplcattivo=0;
         mortocattivo=1;
         contapunti++;
         }
     }
}

Ciò che si voleva ottenere è che per 150 chiamate alla funzione appare l'esplosione alle coordinate xa[array] e ya[array], dopodiché non c'è più l'esigenza di mostrare l'esplosione (viene azzerato il tempo dell'esplosione, viene indicato con mortocattivo=1 che non importa più visualizzare esplosioni).
La funzione viene chiamata dal main. C'è un evidente problema:
- la prima volta dopo che hai colpito un cattivo, array contiene (salvo l'aggiunta del break) l'indice giusto del cattivo colpito
- poi tutte le altre funzioni chiamate dal main modificano inevitabilmente array, facendolo puntare ad un numero diverso (il più delle volte oltre al limite dell'array).
Secondo me devi pensare ad un meccanismo diverso per gestire l'esplosione. No, non serve né un ciclo for, né un break (in mancanza di un ciclo non ha neppure effetto).
Il faut être toujours ivre. Tout est là : c'est l'unique question. Pour ne pas sentir l'horrible fardeau du Temps qui brise vos épaules et vous penche vers la terre,il faut vous enivrer sans trêve...
Avatar utente
zello
Moderatore
 
Post: 2351
Iscritto il: 06/05/02 13:44

Re: Giochino in Dev C++

Postdi Paolo87 » 08/09/08 13:41

Mmmmm,dai adesso vedo come rivedere la cosa,magari rifacendo tutto d'accapo la cosa viene meglio. Se mi riesce come voglio posto qui la risposta
Paolo87
Utente Senior
 
Post: 305
Iscritto il: 26/08/07 09:54
Località: Roma


Torna a Programmazione


Topic correlati a "Giochino in Dev C++":

Antico giochino
Autore: cassioli
Forum: Discussioni
Risposte: 6

Chi c’è in linea

Visitano il forum: Nessuno e 3 ospiti