12-21-2011, 08:00 PM
Сама программа - http://rghost.ru/35530911
(в архиве .exe и настройки)
Проблема в том, когда летят шары, они миграют .. >.<
(в архиве .exe и настройки)
Проблема в том, когда летят шары, они миграют .. >.<
animation.cpp
PHP код:
<?php
#include <stdio.h>
#include <graphics.h>
#include <math.h>
#include "animation.h"
static int BallColors[]={RGB(0,255,0), RGB(0,0,255), RGB(255,0,0), RGB(255,255,0)};
int LoadScene(Scene *sc, char fname[])
{
int i;
sc->ballcount=-1; // ïðèçíàê îøèáêè
FILE *f=fopen(fname, "rt");
if (f)
{
fscanf(f, "%d%d%d%lf%lf%d", &sc->bgcolor, &sc->width, &sc->height, &sc->g, &sc->k, &sc->ballcount);
for (i=0; i<sc->ballcount; i++) sc->balls[i]=ReadBall(f);
if(feof(f)) {sc->ballcount=-1; return 1;}
}
fclose(f);
return 0;
}
void DrawScene(Scene*sc)
{
setbkcolor(sc->bgcolor);
cleardevice();
for (int i=0; i<sc->ballcount; i++)
DrawBall(sc->balls[i]);
}
void twoballs(Scene *sc, Ball *b1, Ball *b2, double dt)
{
int tmp;
double b1x = b1->x + dt*b1->vx;
double b1y = b1->y + dt*b1->vy;
double b2x = b2->x + dt*b2->vx;
double b2y = b2->y + dt*b2->vy;
double Distance = sqrt((b2->x-b1x)*(b2->x-b1x)+(b2->y-b1y)*(b2->y-b1y));
if(Distance <= b1->r+b2->r)
{
//Èçìåíåíèå öâåòà
tmp=b1->color1;
b1->color1=b2->color1;
b2->color1=tmp;
tmp=b1->color2;
b1->color2=b2->color2;
b2->color2=tmp;
//Âñïîìîãàòåëüíûå ðàñ÷åòû
double nx = (b2->x-b1x)/Distance;
double ny = (b2->y-b1y)/Distance;
double nv1 = nx*b1->vx + ny*b1->vy;
double lv1 = ny*b1->vx - nx*b1->vy;
double nv2 = nx*b2->vx + ny*b2->vy;
double lv2 = ny*b2->vx - nx*b2->vy;
//Ïåðåñ÷èòûâàíèå êîîðäèíàò
b1->vx = nx*nv2 + ny*lv1;
b1->vy = ny*nv2 - nx*lv1;
b2->vx = nx*nv1 + ny*lv2;
b2->vy = ny*nv1 - nx*lv2;
}
}
void CalculateScene(Scene *sc, double dt)
{
for (int i=0; i<sc->ballcount; i++)
{
CalcGravity(sc, &(sc->balls[i]), dt);
TryMoveBall(sc, &(sc->balls[i]), dt);
Viscosity(sc, &(sc->balls[i]), dt);
}
for (int i=0; i<sc->ballcount-1; i++)
for (int j=i+1; j<sc->ballcount; j++)
twoballs(sc, &(sc->balls[i]), &(sc->balls[j]), dt);
}
Ball ReadBall(FILE *f)
{
Ball b;
fscanf(f, "%lf%lf%lf%lf%lf%d%d%d", &b.x, &b.y, &b.r, &b.vx, &b.vy, &b.color1, &b.color2, &b.type);
return b;
}
static void DrawBall0(Ball b)
{
setcolor(BallColors[b.color1]);
setlinestyle(SOLID_LINE, 1, 4);
setfillstyle(SOLID_FILL, BallColors[b.color2]);
fillellipse(b.x, b.y, b.r, b.r);
setcolor(BallColors[b.color1]);
setfillstyle(SOLID_FILL, BallColors[b.color1]);
setlinestyle(SOLID_LINE, 1, 2);
moveto(b.x-b.r/10, b.y-b.r/1.5);
lineto(b.x+b.r/10, b.y-b.r/1.5);
lineto(b.x+b.r/2, b.y+b.r/2.5);
lineto(b.x+b.r/3, b.y+b.r/2.5);
lineto(b.x+b.r/4, b.y+b.r/6);
lineto(b.x-b.r/4, b.y+b.r/6);
lineto(b.x-b.r/3, b.y+b.r/2.5);
lineto(b.x-b.r/2, b.y+b.r/2.5);
lineto(b.x-b.r/10, b.y-b.r/1.5);
moveto(b.x, b.y-b.r/2);
lineto(b.x+b.r/7, b.y-b.r/20);
lineto(b.x-b.r/7, b.y-b.r/20);
lineto(b.x, b.y-b.r/2);
floodfill(b.x, b.y, BallColors[b.color1]);
}
static void DrawBall1(Ball b)
{
setcolor(BallColors[b.color1]);
setlinestyle(SOLID_LINE, 1, 4);
setfillstyle(SOLID_FILL, BallColors[b.color2]);
fillellipse(b.x, b.y, b.r, b.r);
setcolor(BallColors[b.color1]);
setfillstyle(SOLID_FILL, BallColors[b.color1]);
setlinestyle(SOLID_LINE, 1, 2);
moveto(b.x+b.r/2, b.y-b.r/1.7);
lineto(b.x-b.r/2, b.y-b.r/1.7);
lineto(b.x-b.r/2, b.y+b.r/1.7);
lineto(b.x+b.r/2, b.y+b.r/1.7);
lineto(b.x+b.r/2, b.y+b.r/2.5);
lineto(b.x-b.r/3.5, b.y+b.r/2.5);
lineto(b.x-b.r/3.5, b.y+b.r/7);
lineto(b.x+b.r/2, b.y+b.r/7);
lineto(b.x+b.r/2, b.y-b.r/20);
lineto(b.x-b.r/3.5, b.y-b.r/20);
lineto(b.x-b.r/3.5, b.y-b.r/2.5);
lineto(b.x+b.r/2, b.y-b.r/2.5);
lineto(b.x+b.r/2, b.y-b.r/1.7);
floodfill(b.x, b.y, BallColors[b.color1]);
}
static void DrawBall2(Ball b)
{
setcolor(BallColors[b.color1]);
setlinestyle(SOLID_LINE, 1, 4);
setfillstyle(SOLID_FILL, BallColors[b.color2]);
fillellipse(b.x, b.y, b.r, b.r);
setcolor(BallColors[b.color1]);
setfillstyle(SOLID_FILL, BallColors[b.color1]);
setlinestyle(SOLID_LINE, 1, 2);
moveto(b.x-b.r/2, b.y-b.r/1.7);
lineto(b.x-b.r/3.5, b.y-b.r/1.7);
lineto(b.x-b.r/3.5, b.y-b.r/10);
lineto(b.x+b.r/3.5, b.y-b.r/10);
lineto(b.x+b.r/3.5, b.y-b.r/1.7);
lineto(b.x+b.r/2, b.y-b.r/1.7);
lineto(b.x+b.r/2, b.y+b.r/1.7);
lineto(b.x+b.r/3.5, b.y+b.r/1.7);
lineto(b.x+b.r/3.5, b.y+b.r/10);
lineto(b.x-b.r/3.5, b.y+b.r/10);
lineto(b.x-b.r/3.5, b.y+b.r/1.7);
lineto(b.x-b.r/2, b.y+b.r/1.7);
lineto(b.x-b.r/2, b.y-b.r/1.7);
floodfill(b.x, b.y, BallColors[b.color1]);
}
static void DrawBall3(Ball b)
{
setcolor(BallColors[b.color1]);
setlinestyle(SOLID_LINE, 1, 4);
setfillstyle(SOLID_FILL, BallColors[b.color2]);
fillellipse(b.x, b.y, b.r, b.r);
setcolor(BallColors[b.color1]);
setfillstyle(SOLID_FILL, BallColors[b.color1]);
setlinestyle(SOLID_LINE, 1, 2);
arc(b.x+b.r/7, b.y-b.r/2.9, 270, 90, b.r/4);
arc(b.x+b.r/7, b.y-b.r/2.9, 270, 90, b.r/6);
moveto(b.x+b.r/7, b.y-b.r/2);
lineto(b.x, b.y-b.r/2);
moveto(b.x+b.r/7, b.y-b.r/1.7);
lineto(b.x-b.r/9, b.y-b.r/1.7);
moveto(b.x+b.r/7, b.y-b.r/5.3);
lineto(b.x, b.y-b.r/5.3);
moveto(b.x+b.r/7, b.y-b.r/10);
lineto(b.x, b.y-b.r/10);
moveto(b.x, b.y-b.r/2);
lineto(b.x, b.y-b.r/5);
moveto(b.x-b.r/9, b.y-b.r/1.7);
lineto(b.x-b.r/9, b.y+b.r/2.5);
lineto(b.x, b.y+b.r/2.5);
lineto(b.x, b.y-b.r/10);
floodfill(b.x, b.y-b.r/6, BallColors[b.color1]);
}
void DrawBall(Ball b)
{
if (b.type==0) DrawBall0(b);
else if (b.type==1) DrawBall1(b);
else if (b.type==2) DrawBall2(b);
else DrawBall3(b);
}
void TryMoveBall(Scene*sc,Ball*b,double dt)
{
double x=b->x+b->vx*dt;
double y=b->y+b->vy*dt;
if(x+b->r>sc->width||x-b->r<0)
{
b->vx*=-1;
if (b->color1==3) b->color1=0;
else b->color1=b->color1+1;
if (b->color2==3) b->color2=0;
else b->color2=b->color2+1;
}
else if (y+b->r>sc->height||y-b->r<0)
{
b->vy*=-1;
if (b->color1==3) b->color1=0;
else b->color1=b->color1+1;
if (b->color2==3) b->color2=0;
else b->color2=b->color2+1;
}
else
{
b->x=x;
b->y=y;
}
}
int SaveState(Scene *sc, char fname[])
{
int i;
FILE *f=fopen(fname, "wt");
if (f)
{
fprintf(f, "%d\n%d\n%d\n%-.0lf\n%-.0lf\n%d", sc->bgcolor, sc->width, sc->height, sc->g, sc->k, sc->ballcount);
for (i=0; i<sc->ballcount; i++)
fprintf(f, "\n%-.0lf %-.0lf %-.0lf %-.0lf %-.0lf %d %d %d", sc->balls[i].x, sc->balls[i].y, sc->balls[i].r, sc->balls[i].vx, sc->balls[i].vy, sc->balls[i].color1, sc->balls[i].color2, sc->balls[i].type);
if(feof(f)) {return 1;}
}
fclose(f);
return 0;
}
int LoadState(Scene *sc, char fname[])
{
int i;
FILE *f=fopen(fname, "rt");
if (f)
{
fscanf(f, "%d%d%d%lf%lf%d", &sc->bgcolor, &sc->width, &sc->height, &sc->g, &sc->k, &sc->ballcount);
for (i=0; i<sc->ballcount; i++)
fscanf(f, "%lf%lf%lf%lf%lf%d%d%d", &sc->balls[i].x, &sc->balls[i].y, &sc->balls[i].r, &sc->balls[i].vx, &sc->balls[i].vy, &sc->balls[i].color1, &sc->balls[i].color2, &sc->balls[i].type);
if(feof(f)) {return 1;}
}
fclose(f);
return 0;
}
void CalcGravity(Scene *sc, Ball *b, double dt)
{
b->vy+=sc->g*dt;
}
void Viscosity(Scene *sc, Ball *b, double dt)
{
b->vx = b->vx > 0 ? b->vx - sc->k*dt : b->vx + sc->k*dt;
b->vy = b->vy > 0 ? b->vy - sc->k*dt : b->vy + sc->k*dt;
}
animation.h
PHP код:
<?php
#ifndef ANIMATION_H
#define ANIMATION_H
struct Ball
{
double x; // x - êîîðäèíàòà øàðèêà
double y; // y - êîîðäèíàòà øàðèêà
double r; // ðàäèóñ øàðèêà
double vx; //ñêîðîñòü
double vy; //ñêîðîñòü
int color1, color2; //öâåò 1, öâåò2
int type; // òèï øàðèêà
};
struct Scene
{
//Îáùèå ïàðàìåòðû
int bgcolor; //öâåò ôîíà
int width; //øèðèíà ñöåíû
int height; //âûñîòà ñöåíû
double g; //óñêîðåíèå ñâîáîäíîãî ïàäåíèÿ
double k; //êîýôèöèåíò òðåíèÿ
//Îáúåêòû íà ñöåíå
int ballcount; // êîë-âî øàðèêîâ
Ball balls[100]; // Ìàññèâ øàðèêîâ
};
int LoadScene(Scene *s, char fname[]);
void DrawScene(Scene *sc);
void CalculateScene(Scene *sc, double dt);
Ball ReadBall(FILE *f);
void DrawBall(Ball b);
void TryMoveBall(Scene*sc,Ball*b,double dt);
void CalcGravity(Scene *sc, Ball *b, double dt);
void twoballs(Scene *sc, Ball *b1, Ball *b2, double dt);
static void DrawBall0(Ball b);
static void DrawBall1(Ball b);
static void DrawBall2(Ball b);
static void DrawBall3(Ball b);
int SaveState(Scene *sc, char fname[]);
int LoadState(Scene *sc, char fname[]);
void Viscosity(Scene *sc, Ball *b, double dt);
#endif