CARVIEW |
Select Language
HTTP/2 302
server: nginx
date: Sat, 16 Aug 2025 08:14:05 GMT
content-type: text/plain; charset=utf-8
content-length: 0
x-archive-redirect-reason: found capture at 20080612194403
location: https://web.archive.org/web/20080612194403/https://www.daniweb.com/code/snippet744.html
server-timing: captures_list;dur=0.940638, exclusion.robots;dur=0.042574, exclusion.robots.policy;dur=0.018891, esindex;dur=0.032164, cdx.remote;dur=5.750399, LoadShardBlock;dur=175.290566, PetaboxLoader3.datanode;dur=61.021084, PetaboxLoader3.resolve;dur=47.335910
x-app-server: wwwb-app211
x-ts: 302
x-tr: 213
server-timing: TR;dur=0,Tw;dur=0,Tc;dur=0
set-cookie: wb-p-SERVER=wwwb-app211; path=/
x-location: All
x-rl: 0
x-na: 0
x-page-cache: MISS
server-timing: MISS
x-nid: DigitalOcean
referrer-policy: no-referrer-when-downgrade
permissions-policy: interest-cohort=()
HTTP/2 200
server: nginx
date: Sat, 16 Aug 2025 08:14:07 GMT
content-type: text/html; charset=utf-8
x-archive-orig-date: Thu, 12 Jun 2008 19:43:36 GMT
x-archive-orig-server: Apache/2.2
x-archive-orig-x-powered-by: PHP/5.1.6
x-archive-orig-set-cookie: bblastvisit=1213297628; expires=Fri, 12-Jun-2009 19:43:36 GMT; path=/; domain=.daniweb.com
x-archive-orig-set-cookie: bblastactivity=0; expires=Fri, 12-Jun-2009 19:43:36 GMT; path=/; domain=.daniweb.com
x-archive-orig-cache-control: private
x-archive-orig-pragma: private
x-archive-orig-connection: close
x-archive-guessed-content-type: text/html
x-archive-guessed-charset: utf-8
memento-datetime: Thu, 12 Jun 2008 19:44:03 GMT
link: ; rel="original", ; rel="timemap"; type="application/link-format", ; rel="timegate", ; rel="first memento"; datetime="Sat, 03 Nov 2007 14:52:27 GMT", ; rel="prev memento"; datetime="Sun, 06 Jan 2008 16:03:19 GMT", ; rel="memento"; datetime="Thu, 12 Jun 2008 19:44:03 GMT", ; rel="next memento"; datetime="Fri, 25 Jul 2008 14:47:18 GMT", ; rel="last memento"; datetime="Tue, 03 Mar 2009 15:57:02 GMT"
content-security-policy: default-src 'self' 'unsafe-eval' 'unsafe-inline' data: blob: archive.org web.archive.org web-static.archive.org wayback-api.archive.org athena.archive.org analytics.archive.org pragma.archivelab.org wwwb-events.archive.org
x-archive-src: 52_4_20080612185533_crawl107-c/52_4_20080612194304_crawl104.arc.gz
server-timing: captures_list;dur=1.449952, exclusion.robots;dur=0.019837, exclusion.robots.policy;dur=0.010064, esindex;dur=0.014236, cdx.remote;dur=13.352437, LoadShardBlock;dur=279.627157, PetaboxLoader3.datanode;dur=362.301402, PetaboxLoader3.resolve;dur=1240.478417, load_resource;dur=1375.658933
x-app-server: wwwb-app211
x-ts: 200
x-tr: 1852
server-timing: TR;dur=0,Tw;dur=0,Tc;dur=0
x-location: All
x-rl: 0
x-na: 0
x-page-cache: MISS
server-timing: MISS
x-nid: DigitalOcean
referrer-policy: no-referrer-when-downgrade
permissions-policy: interest-cohort=()
content-encoding: gzip
GTK Asteroids - c
GTK Asteroids
•
•
•
•

What is DaniWeb IT Discussion Community?
You're currently browsing the C section within the Software Development category of DaniWeb, a massive community of 348,136 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 4,283 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our C advertiser:
You likely want something graphical, where the things move. GTK version of the classic arcade game Asteroids.
Last edited : Sep 1st, 2007.
/* Name GTK Asteroids -- asteroids style arcade game Description GTK version 30 Aug 2007 by TkTkorrovi in DaniWeb of the original Xasteroids version 5, 9 Feb 1993 Keys Please see the function key_press_event License Copyright 1990 by Phil Goetz <goetz@cs.buffalo.edu> If you modify the game, feel free to post your version, provided that you retain the original copyright notice, the credits, and note which version yours was derived from and its release date, what changes you made, and your release date. Contributors Peter Phillips <pphillip@cs.ubc.ca> Pat Ryan <pat@jaameri.gsfc.nasa.gov> Craig Smith <csmith@cscs.UUCP> Doug Merritt <doug@netcom.com> Stephen McCamant <alias@mcs.com> */ #include <gtk/gtk.h> #include <gdk/gdkkeysyms.h> #include <stdlib.h> #include <stdio.h> #include <time.h> #include <math.h> #define M_BIG 8.0 /* masses */ #define M_MED 4.0 #define M_SMALL 1.0 #define M_SHIP 1.5 #define M_ENEMY 1.0 #define M_BULLET 0.1 #define ENEMY 96 /* indexes for obj, the order */ #define ENEMYBUL 97 /* they are in is important */ #define FBUL 98 #define LASTBUL 102 #define SHIP 103 #define LASTOBJ 103 #define LASTSHAPE 7 #define SHIPSIZE 28 #define BMAX 300 /* max particles in a boom */ #define LH 20 /* height of font */ #define pi 3.1415926535897932384 enum {ASTSHAPE1, ASTSHAPE2, ASTSHAPE3, ENBULSH, BULSHAPE, SHIPSHAPE, SHIPTHRSHAPE, ENEMYSHAPE}; #define dot(a, b) (a.x * b.x + a.y * b.y) /* dot product */ #define rotinert(a) (obj [a].mass * shapesize [obj [a].shape] * \ shapesize [obj [a].shape]) /* rotational inertia */ struct boomtype { struct boomtype *next; int dur; int part; double bcoord [BMAX] [2]; double bvec [BMAX] [2]; } *blist; struct { int shape; int alive; int time; double mass; double x, y; double xvel, yvel; double rot; double rotvel; } obj [SHIP + 1]; struct { /* if you change shapes, change also shapesize */ double angle; /* 0 >, pi / 2 v, pi <, 3 * pi / 2 ^ */ int length; /* pixels */ } shapes [] [12] = { { {0, 0}, {3 * pi / 2, 40}, {0, 20}, {pi / 4, 28}, {pi / 2, 40}, {3 * pi / 4, 28}, {pi, 40}, {5 * pi / 4, 28}, {3 * pi / 2, 40}, {7 * pi / 4, 28}, {0, 20}, {0, 0}, }, { {0, 0}, {3 * pi / 2, 20}, {0, 10}, {pi / 4, 14}, {pi / 2, 20}, {3 * pi / 4, 14}, {pi, 20}, {5 * pi / 4, 14}, {3 * pi / 2, 20}, {7 * pi / 4, 14}, {0, 10}, {0, 0}, }, { {0, 0}, {3 * pi / 2, 10}, {0, 5}, {pi / 4, 7}, {pi / 2, 10}, {3 * pi / 4, 7}, {pi, 10}, {5 * pi / 4, 7}, {3 * pi / 2, 10}, {7 * pi / 4, 7}, {0, 5}, {0, 0}, }, { {0, 0}, {7 * pi / 4, 4}, {pi / 4, 4}, {3 * pi / 4, 4}, {5 * pi / 4, 4}, {0, 0}, }, { {0, 0}, {0, 10}, {0, 0}, }, { {0, 0}, {5 * pi / 4, 28}, {0, 20}, {pi / 4, 28}, {3 * pi / 4, 28}, {pi, 20}, {7 * pi / 4, 28}, {0, 0}, }, { {0, 0}, {5 * pi / 4, 28}, {0, 20}, {pi / 4, 28}, {3 * pi / 4, 28}, {pi, 20}, {7 * pi / 4, 28}, {3 * pi / 4, 7}, {9 * pi / 8, 13}, {15 * pi / 8, 13}, {0, 0}, }, { {0, 0}, {pi, 20}, {7 * pi / 4, 28}, {pi / 4, 28}, {pi, 20}, {0, 0} } }; double dscale = 1, speedscale = 1; int width = 800, height = 600, delay = 8192, cntstart = 1, crashed, pausg, newship, quit, newgame, highscore, level, numasts, ships, score, shield, energy; GdkPixmap *pixmap; cairo_t *cr; void linespec (double *e1, double *e2, int s, int n, double rot, double *a, double *b, double *c) { e2 [0] = e1 [0] + shapes [s] [n].length * dscale * cos (shapes [s] [n].angle + rot); e2 [1] = e1 [1] + shapes [s] [n].length * dscale * sin (shapes [s] [n].angle + rot); *a = e2 [1] - e1 [1]; /* use classic line intersection algorithm */ *b = e1 [0] - e2 [0]; *c = *a * e1 [0] + *b * e1 [1]; } int collide (int a, int b) { int diff, sa, sb, xd, yd, n, i, j; double a1 [2], a2 [2], b1 [2], b2 [2], xcross, aa, ba, ca, ab, bb, cb, det, shapesize [] = {44, 21, 10, 2, 1, SHIPSIZE + 1, 35, 20}; sa = obj [a].shape; sb = obj [b].shape; xd = obj [a].x - obj [b].x; yd = obj [a].y - obj [b].y; diff = sqrt (xd * xd + yd * yd); if (diff >= (shapesize [sa] + shapesize [sb]) * dscale) return 0; if (b == SHIP && shield) return 1; /* shield collision */ if (sa < SHIPSHAPE && sb < SHIPSHAPE) return 1; /* original game */ a1 [0] = obj [a].x; a1 [1] = obj [a].y; for (i = 1; shapes [sa] [i].length; i++) { linespec (a1, a2, sa, i, obj [a].rot, &aa, &ba, &ca); b1 [0] = obj [b].x; b1 [1] = obj [b].y; for (j = 1; shapes [sb] [j].length; j++) { linespec (b1, b2, sb, j, obj [b].rot, &ab, &bb, &cb); if (!(det = aa * bb - ab * ba)) return 1; xcross = (bb * ca - ba * cb) / det; if ((xcross - a1 [0]) * (a2 [0] - xcross) > 0 && (xcross - b1 [0]) * (b2 [0] - xcross) > 0) return 1; /* collision */ for (n = 0; n < 2; n++) b1 [n] = b2 [n]; } for (n = 0; n < 2; n++) a1 [n] = a2 [n]; } return 0; /* no collision */ } /* |vapab| = |va| * sin (a) = |va x ab| / |ab| |vapab| = |va| * cos (pi / 2 - a) = (va dot (perp. to ab)) / |ab| (cross product when 3rd coord is 0) mass (a) * va_ab + mass (b) * vb_ab = mass (a) * va_abf + mass (b) * vb_abf va_ab + va_abf = vb_ab + vb_abf (dividing eq for conservation of kinetic energy by eq for cons. of momentum) */ void bounce (int a, int b) { double rotrat, temp; int shapesize [] = {44, 21, 10, 2, 1, SHIPSIZE + 1, 35, 20}; struct { double x; double y; double mag; } ab, va, vb, /* vector from a to b, velocities */ va_ab, vb_ab, vapab, vbpab, /* along, perpenticular to ab */ va_abf, vb_abf; /* post-collision velocities along ab */ va.x = obj [a].xvel; va.y = obj [a].yvel; vb.x = obj [b].xvel; vb.y = obj [b].yvel; ab.x = obj [b].x - obj [a].x; ab.y = obj [b].y - obj [a].y; ab.mag = sqrt (ab.x * ab.x + ab.y * ab.y); va_ab.mag = dot (va, ab) / ab.mag; /* va_ab = va * cos (a) = */ va_ab.x = (ab.x * va_ab.mag) / ab.mag; /* (va dot ab) / |ab| */ va_ab.y = (ab.y * va_ab.mag) / ab.mag; vb_ab.mag = dot (vb, ab) / ab.mag; vb_ab.x = (ab.x * vb_ab.mag) / ab.mag; vb_ab.y = (ab.y * vb_ab.mag) / ab.mag; if (va_ab.mag - vb_ab.mag < 0) return; temp = (va.y * ab.x - va.x * ab.y) / (ab.mag * ab.mag); vapab.x = -ab.y * temp; vapab.y = ab.x * temp; temp = (vb.x * ab.y - vb.y * ab.x) / (ab.mag * ab.mag); vbpab.x = -ab.y * temp; vbpab.y = ab.x * temp; temp = obj [a].mass / obj [b].mass; vb_abf.x = (temp * (2 * va_ab.x - vb_ab.x) + vb_ab.x) / (1 + temp); vb_abf.y = (temp * (2 * va_ab.y - vb_ab.y) + vb_ab.y) / (1 + temp); va_abf.x = vb_abf.x + vb_ab.x - va_ab.x; va_abf.y = vb_abf.y + vb_ab.y - va_ab.y; obj [a].xvel = va_abf.x + vapab.x; obj [a].yvel = va_abf.y + vapab.y; obj [b].xvel = vb_abf.x + vbpab.x; obj [b].yvel = vb_abf.y + vbpab.y; rotrat = rotinert (a) / rotinert (b); temp = rotrat * (2 * obj [a].rotvel - obj [b].rotvel) / (1 + rotrat); obj [a].rotvel = temp + obj [b].rotvel - obj [a].rotvel; obj [b].rotvel = temp; /* rotational velocity exchange */ } void boom (int ob, int particles, int duration) { int i; struct boomtype *b; double angle, length, x, y; b = malloc (sizeof (struct boomtype)); b->dur = 5 * duration; b->part = particles; x = obj [ob].x; y = obj [ob].y; for (i = 0; i < particles; i++) { b->bcoord [i] [0] = x; b->bcoord [i] [1] = y; angle = (rand () % 100) * pi / 50.0; length = 3 + rand () % 7; b->bvec [i] [0] = cos (angle) * length + obj [ob].xvel; b->bvec [i] [1] = sin (angle) * length + obj [ob].yvel; } b->next = blist; blist = b; } void newast (int *a, int *b) { for (*b = 0; obj [*b].alive; (*b)++); obj [*b].x = obj [*a].x; obj [*b].y = obj [*a].y; obj [*b].xvel = obj [*a].xvel; obj [*b].yvel = obj [*a].yvel; obj [*b].alive++; } void upscore (int killer, int up) { if (killer != ENEMYBUL && killer != SHIP) score += up; } void blastpair (int a, int b) { int n; n = rand () % 64; obj [a].xvel = obj [a].xvel + cos (n); /* add random */ obj [a].yvel = obj [a].yvel + sin (n); /* velocity vector */ obj [b].xvel = obj [b].xvel - cos (n); obj [b].yvel = obj [b].yvel - sin (n); obj [a].rotvel = obj [a].rotvel + 0.05; obj [b].rotvel = obj [b].rotvel - 0.05; } void killasteroid (int killer, int a) { int b = 0, oldb, i; if (obj [a].shape == ASTSHAPE1) { newast (&a, &b); obj [b].shape = ASTSHAPE2; obj [b].mass = M_MED; obj [a].shape = ASTSHAPE2; obj [a].mass = M_MED; blastpair (a, b); boom (a, 30, 12); numasts++; if (numasts == 2) /* big asteroid was last */ upscore (killer, 25 + level * 2000); else upscore (killer, 25); } else if (obj [a].shape == ASTSHAPE2) { for (i = 0; i < 3; i++) { oldb = b; newast (&a, &b); obj [b].shape = ASTSHAPE3; obj [b].mass = M_SMALL; if (i == 1) blastpair (oldb, b); } obj [a].shape = ASTSHAPE3; obj [a].mass = M_SMALL; blastpair (b, a); boom (a, 20, 10); if (numasts == 1) upscore (killer, 500 * level); numasts = numasts + 3; upscore (killer, 50); } else if (obj [a].shape == ASTSHAPE3) { boom (a, 10, 8); obj [a].alive = 0; numasts--; upscore (killer, 100); } else { /* enemy (ship or bullet) */ boom (a, 9, 7); obj [a].alive = 0; upscore (killer, 500); } } void moveobjs () { int i, j; double *temp; struct boomtype *prevb, *b; prevb = blist; for (b = blist; b; ) if (--b->dur) { /* move */ for (i = 0; i < b->part; i++) for (j = 0; j < 2; j++) b->bcoord [i] [j] += 0.2 * b->bvec [i] [j]; prevb = b; b = b->next; } else if (b != blist) { /* delete */ prevb->next = b->next; free (b); b = prevb->next; } else if (b->next) { blist = b->next; free (b); prevb = blist; b = prevb->next; } else { blist = NULL; free (b); b = NULL; } for (i = 0; i < LASTOBJ + 1; i++) { if (!obj [i].alive) continue; temp = &obj [i].x; *temp = *temp + obj [i].xvel * speedscale; while (*temp < 0) *temp = *temp + width; while (*temp > width) *temp = *temp - width; temp = &obj [i].y; *temp = *temp + obj [i].yvel * speedscale; while (*temp < 0) *temp = *temp + height; while (*temp > height) *temp = *temp - height; obj [i].rot = obj [i].rot + obj [i].rotvel; } for (i = 0; i < FBUL; i++) { if (!obj [i].alive) continue; if (obj [SHIP].alive && collide (i, SHIP)) { if (shield) bounce (SHIP, i); else { crashed = 1; ships--; obj [SHIP].alive = 0; killasteroid (SHIP, i); continue; } } for (j = ENEMYBUL; j < LASTBUL + 1; j++) if (obj [j].alive && collide (i, j) && (j != ENEMYBUL || (i != ENEMYBUL && i != ENEMY))) { obj [j].alive = 0; /* kill bullet */ if (obj [i].alive) killasteroid (j, i); } /* not 2 bullets for one asteroid */ } } void drawframe (GtkWidget *da, PangoLayout *text) { int shape, i, j; char buf [FILENAME_MAX]; double angle, length, rot; struct boomtype *b; cairo_set_line_width (cr, 0.5); cairo_set_source_rgb (cr, 1, 1, 1); cairo_paint (cr); cairo_set_source_rgb (cr, 0, 0, 0.57); cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE); for (b = blist; b; b = b->next) for (i = 0; i < b->part; i++) { cairo_move_to (cr, b->bcoord [i] [0], b->bcoord [i] [1]); cairo_rel_line_to (cr, 1, 1); } cairo_stroke (cr); cairo_set_antialias (cr, CAIRO_ANTIALIAS_DEFAULT); if (shield && obj [SHIP].alive) cairo_arc (cr, obj [SHIP].x, obj [SHIP].y, abs (dscale * SHIPSIZE), 0, pi * 2); for (i = 0; i <= LASTOBJ; i++) { if (!obj [i].alive) continue; shape = obj [i].shape; rot = obj [i].rot; cairo_move_to (cr, obj [i].x, obj [i].y); for (j = 1; shapes [shape] [j].length; j++) { angle = shapes [shape] [j].angle + rot; length = shapes [shape] [j].length * dscale; cairo_rel_line_to (cr, length * cos (angle), length * sin (angle)); } cairo_stroke (cr); } pango_layout_set_text (text, " GTK version\n\n" "by TkTkorrovi in DaniWeb\n\n of Xasteroids", -1); cairo_move_to (cr, width / 2 - 120, height / 2 - 3 * LH); if (!ships) pango_cairo_show_layout (cr, text); cairo_set_source_rgb (cr, 1, 1, 1); cairo_rectangle (cr, 0, height - LH, width, height); cairo_fill (cr); cairo_set_source_rgb (cr, 0, 0, 0.57); cairo_rectangle (cr, 340, height - LH + 6, energy >> 1, 10); cairo_fill (cr); sprintf (buf, "Ships:%2d Score:%6d Shield: High:%6d", ships, score, highscore); pango_layout_set_text (text, buf, -1); cairo_move_to (cr, 0, height - LH); pango_cairo_show_layout (cr, text); gtk_widget_queue_draw_area (da, 0, 0, width, height); } /* finally order expose event, only there we can draw to window */ void makeasts () { int i, n; for (i = 0; i < SHIP; i++) obj [i].alive = 0; /* except ship */ for (i = ENEMYBUL; i < LASTBUL + 1; i++) obj [i].time = 0; for (i = 0; i < (level > 8 ? 8 : level + 4); i++) { n = rand () % 128; obj [i].x = n > 63 ? n : width - n; n = rand () % 128; obj [i].y = n > 63 ? n : height - n; obj [i].rot = rand () % 8; /* ??? */ obj [i].rotvel = (rand () % 256) / 2048.; n = rand () % 256; obj [i].xvel = cos (n); obj [i].yvel = sin (n); obj [i].shape = ASTSHAPE1; obj [i].mass = M_BIG; obj [i].alive = 1; } numasts = i; } void fire () { double *shiprot, cosrot, sinrot; static int nextbul = FBUL; obj [nextbul].alive++; shiprot = &obj [SHIP].rot; cosrot = cos (*shiprot); sinrot = sin (*shiprot); obj [nextbul].x = obj [SHIP].x + 20 * cosrot * dscale; obj [nextbul].y = obj [SHIP].y + 20 * sinrot * dscale; obj [nextbul].xvel = obj [SHIP].xvel + 10 * cosrot; obj [nextbul].yvel = obj [SHIP].yvel + 10 * sinrot; obj [nextbul].rot = *shiprot; obj [nextbul].time = width / (speedscale * 11) / 2; if (++nextbul == LASTBUL + 1) nextbul = FBUL; } void loop (GtkWidget *da, PangoLayout *text) { double dist, dx, dy; int enemycount = 20, counter = 0, i; while (numasts && !newship && !newgame && !quit) { for (i = FBUL; i < LASTBUL + 1; i++) if (obj [i].alive) if (!--obj [i].time) obj [i].alive = 0; if (pausg) for (g_usleep (delay); g_main_context_iteration (NULL, 0); ); if (newship || newgame || pausg || quit) continue; moveobjs (); if (shield) energy--; if (!energy) shield = 0; if (!ships) obj [SHIP].alive = 0; if (score > highscore) highscore = score; if (!counter) { counter = cntstart; if (crashed) { crashed--; boom (SHIP, BMAX, 70); } drawframe (da, text); } counter--; i = rand () % 256; if (!obj [ENEMY].alive) { if (i < level && rand () % 256 < level * 10) { obj [ENEMY].alive = 1; obj [ENEMY].x = 0; obj [ENEMY].y = height / 4 + rand () % 256; obj [ENEMY].xvel = 0.4 + level / 3.; obj [ENEMY].yvel = 0; obj [ENEMY].rot = 0; obj [ENEMY].rotvel = 0; } } else { i += obj [SHIP].y > obj [ENEMY].y ? level >> 1 : -(level >> 1); obj [ENEMY].yvel += i > 128 + 6 * obj [ENEMY].yvel ? .5 : -.5; } if (!--enemycount) { enemycount = 100; if (obj [ENEMY].alive) { obj [ENEMYBUL].alive++; obj [ENEMYBUL].x = obj [ENEMY].x; obj [ENEMYBUL].y = obj [ENEMY].y; dx = obj [SHIP].x - obj [ENEMY].x; dy = obj [SHIP].y - obj [ENEMY].y; dist = sqrt (dx * dx + dy * dy); obj [ENEMYBUL].xvel = 3 * dx / dist; obj [ENEMYBUL].yvel = 3 * dy / dist; } else obj [ENEMYBUL].alive = 0; } for (g_usleep (delay); g_main_context_iteration (NULL, 0); ); } } gint key_press_event (GtkWidget *widget, GdkEventKey *event) { if (shield) return 1; switch (event->keyval) { case GDK_Left: /* rotate counterclockwise */ case GDK_e: obj [SHIP].rotvel = -.1; break; case GDK_Right: /* rotate clockwise */ case GDK_r: obj [SHIP].rotvel = .1; break; case GDK_w: /* rotate 45 degrees counterclockwise */ obj [SHIP].rot -= pi / 4; break; case GDK_t: /* rotate 45 degrees clockwise */ obj [SHIP].rot += pi / 4; break; case GDK_d: /* increase ccwise rotational velocity */ obj [SHIP].rotvel = obj [SHIP].rotvel - .02; break; case GDK_f: /* increase clockwise rotational velocity */ obj [SHIP].rotvel = obj [SHIP].rotvel + .02; break; case GDK_Up: /* thrust */ case GDK_o: obj [SHIP].xvel += cos (obj [SHIP].rot); obj [SHIP].yvel += sin (obj [SHIP].rot); obj [SHIP].shape = SHIPTHRSHAPE; break; case GDK_Control_L: /* fire */ case GDK_Control_R: case GDK_p: if (obj [SHIP].alive) fire (); break; case GDK_space: /* hyperspace */ obj [SHIP].x = rand () % width; obj [SHIP].y = rand () % height; break; case GDK_Down: /* shield */ case GDK_grave: if (energy) shield = 1; break; case GDK_period: /* decrease delay -- speed game up */ if (delay > 1) delay >>= 1; break; case GDK_comma: /* increase delay */ if (delay < 500000l) delay <<= 1; break; case GDK_m: /* decrease drawscale -- may go negative */ dscale -= .1; break; case GDK_n: /* increase drawscale */ dscale += .1; break; case GDK_2: /* increase speedscale */ speedscale += .1; break; case GDK_1: /* decrease speedscale */ speedscale -= .1; break; case GDK_b: /* increase moves/update */ if (cntstart < 10000) cntstart++; break; case GDK_v: /* decrease moves/update */ if (cntstart > 1) cntstart--; break; case GDK_Escape: /* pause */ pausg = 1 - pausg; break; case GDK_plus: /* cheat */ ships++; break; case GDK_q: /* quit */ quit = 1; break; case GDK_s: /* new ship */ if (obj [SHIP].alive) break; if (!ships) newgame = 1; if (ships) newship = 1; } return 1; } gint key_release_event (GtkWidget *widget, GdkEventKey *event) { switch (event->keyval) { case GDK_Left: case GDK_e: case GDK_Right: case GDK_r: obj [SHIP].rotvel = 0; break; case GDK_Up: case GDK_o: obj [SHIP].shape = SHIPSHAPE; break; case GDK_Down: case GDK_grave: shield = 0; } return 1; } static gboolean expose_event (GtkWidget *widget, GdkEventExpose *event) { gdk_draw_drawable (widget->window, widget->style->white_gc, pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); return 0; } static gboolean configure_event (GtkWidget *widget, GdkEventConfigure *event) { width = widget->allocation.width; height = widget->allocation.height; if (pixmap) g_object_unref (pixmap); if (cr) cairo_destroy (cr); pixmap = gdk_pixmap_new (widget->window, width, height, -1); cr = gdk_cairo_create (pixmap); return 1; } gint shut () { quit = 1; return 0; } int main (int argc, char **argv) { int i; struct boomtype *b; GtkWidget *window, *da; PangoFontDescription *font; PangoLayout *text; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_set_size_request (window, width, height); gtk_window_set_title (GTK_WINDOW (window), "GTK Asteroids"); gtk_window_set_resizable (GTK_WINDOW (window), 1); da = gtk_drawing_area_new (); gtk_container_add (GTK_CONTAINER (window), da); gtk_widget_set_events (da, GDK_EXPOSURE_MASK); gtk_widget_set_events (window, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); g_signal_connect (window, "delete_event", G_CALLBACK (shut), NULL); g_signal_connect (G_OBJECT (window), "key_press_event", G_CALLBACK (key_press_event), NULL); g_signal_connect (G_OBJECT (window), "key_release_event", G_CALLBACK (key_release_event), NULL); g_signal_connect (G_OBJECT (da), "expose_event", G_CALLBACK (expose_event), NULL); g_signal_connect (G_OBJECT (da),"configure_event", G_CALLBACK (configure_event), NULL); gtk_widget_show_all (window); /* before creating pixmap, gc etc */ text = gtk_widget_create_pango_layout (da, ""); font = pango_font_description_from_string ("monospace bold"); pango_font_description_set_absolute_size (font, 16 * PANGO_SCALE); pango_layout_set_font_description (text, font); srand (time (0)); obj [SHIP].shape = SHIPSHAPE; obj [SHIP].mass = M_SHIP; obj [ENEMY].shape = ENEMYSHAPE; obj [ENEMY].mass = M_ENEMY; obj [ENEMYBUL].shape = ENBULSH; obj [ENEMYBUL].mass = M_BULLET; for (i = FBUL; i < LASTBUL + 1; i++) { obj [i].shape = BULSHAPE; obj [i].mass = M_BULLET; } while (!quit) { newgame = 0; /* newgame */ ships = 3; score = 0; for (level = 0; ;) { if (!newship) { if (level < 15) level++; makeasts (); } newship = 0; /* newship */ if (!obj [SHIP].alive) { obj [SHIP].x = width / 2; obj [SHIP].y = (height - LH) / 2; obj [SHIP].xvel = 0; obj [SHIP].yvel = 0; obj [SHIP].rot = 3 * pi / 2; obj [SHIP].rotvel = 0; energy = 80; shield = 0; } obj [SHIP].alive = (ships > 0); crashed = 0; loop (da, text); if (newgame || quit) break; } } for (b = blist; b; b = b->next) b->dur = 1; moveobjs (); printf ("Your high score was %d\n", highscore); pango_font_description_free (font); cairo_destroy (cr); g_object_unref (pixmap); g_object_unref (text); return 0; }
Comments (Newest First)
TkTkorrovi | Junior Poster | Aug 29th, 2007

•
•
•
•
I have a new version which uses cairo, the graphics is antialiased, and no graphics contexts nowhere... It would be up when i can put it up. I honestly don't see now anything to make better, if someone thinks that anythyng is wrong, then please say... The new version is somewhat slow in windows, i think antialiasing is badly implemented there, if it's slow for you also, take the antialiasing off, no such problems in linux.
TkTkorrovi | Junior Poster | Aug 26th, 2007

•
•
•
•
Who argues that the code in this game is not that good, it's right, it isn't. But then one may look at the debian source package, how much more horrible it was... What would help here is writing the whole thing from scratch, which is not that difficult and likely would also result in much shorter code. But this is not what i'm going to do because my aim was only to port that game from xlib to gtk, which is simple at least because the graphics functions of the two are almost the same, i mean the standard gdk functions. At least i who almost never have to use such graphics functions, would never need any more advanced functions from cairo or such.
TkTkorrovi | Junior Poster | Aug 14th, 2007

•
•
•
•
I created this thread https://www.daniweb.com/forums/post41...tml#post418804 about how to install GTK and MinGW in Windows, and how to compile GTK programs there. All that is much easier in Linux and Mac.
TkTkorrovi | Junior Poster | Aug 13th, 2007

•
•
•
•
I'm glad that you like it
There is a new version up now, but i don't think that i would change it again, as i don't know any more what to make better... This once very popular vector asteroids game is likely not good as a game any more, but now it can serve as a programming example. Because GTK is a cross-platform library, this code compiles exactly as it is in linux, mingw (windows), and likely also in mac and other platforms.

cscgal | The Queen of DaniWeb | Aug 10th, 2007

•
•
•
•
Thank you for contributing this

TkTkorrovi | Junior Poster | Aug 8th, 2007

•
•
•
•
Thanks to Samreid, in #DaniWeb irc channel, for testing this code in Debian. Based on that, you should have GTK development package installed in Linux, to compile GTK applications. If something is wrong, or you are not sure, run "apt-get install libgtk2.0-dev" in Debian, guess this should also work in Ubuntu. It also appeared useful to change the font in the code, from "dejavu sans mono bold 12" to "mono bold 12", because not all have dejavu font installed, or for some reason that font doesn't work, and the result is the default size, which is usually smaller and would cause incorrect placement of text.
Post Comment
•
•
•
•
DaniWeb Marketplace (Sponsored Links)
Forum Highlights
- C Forum
- Today's Posts
- Unanswered Threads
Related Features
DANIWEB FEATURE INDEX
Advertisement
Statistics