001 /*
002 *
003 * Created: Jun 7 2006
004 *
005 * Copyright (C) 1999-2000 Fabien Sanglard
006 *
007 * This program is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU General Public License
009 * as published by the Free Software Foundation; either version 2
010 * of the License, or (at your option) any later version.
011 *
012 * This program is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015 * GNU General Public License for more details.
016 *
017 * You should have received a copy of the GNU General Public License
018 * along with this program; if not, write to the Free Software
019 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020 */
021
022 package rtype.entity;
023
024 import org.lwjgl.opengl.GL11;
025 import org.lwjgl.util.vector.Vector2f;
026
027 import rtype.Layer;
028 import rtype.Prototyp;
029
030 public class HomingMissile extends AnimatedEntity
031 {
032
033 private Entity target = null;
034 private float maxRadianManiability = 0 ;
035
036 public HomingMissile(Layer targetLayer, float maxRadianManiability)
037 {
038 this.target = acquiereNewTarget(targetLayer);
039 this.maxRadianManiability = maxRadianManiability;
040 this.target = target;
041 this.type = MISSILE;
042 init();
043 this.animationSpeed = 40;
044 setRatio(0.25f);
045 this.life = 2;
046 //this.rotation = 180;
047 }
048
049 private Entity acquiereNewTarget(Layer targetLayer) {
050
051 if (targetLayer.entities.size() == 0)
052 return null;
053 else
054 return targetLayer.entities.get(0);
055
056
057 }
058
059 public void draw()
060 {
061
062 animationCursor += animationSpeed * tick ;
063 animationCursor %= animationTextures.length;
064
065 GL11.glLoadIdentity();
066 GL11.glTranslatef(position.x,position.y,Prototyp.DEFAULT_Z); // Translate Into/Out Of The Screen By z
067 GL11.glRotatef(this.rotation,0f,0f,1f);
068
069 GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.animationTextures[(int)animationCursor].getTextureId() );
070
071 GL11.glBlendFunc(GL11.GL_SRC_ALPHA,GL11.GL_ONE_MINUS_SRC_ALPHA);
072
073
074 GL11.glBegin(GL11.GL_QUADS);
075 {
076 GL11.glTexCoord2f(textureRight,textureUp); //Upper right
077 GL11.glVertex2f(width, -height);
078
079 GL11.glTexCoord2f(textureLeft,textureUp); //Upper left
080 GL11.glVertex2f(-width, -height);
081
082 GL11.glTexCoord2f(textureLeft,textureDown); //Lower left
083 GL11.glVertex2f(-width,height);
084
085 GL11.glTexCoord2f(textureRight,textureDown); // Lower right
086 GL11.glVertex2f(width,height);
087
088 }
089 GL11.glEnd();
090
091 }
092
093 Smoke smoke = null;
094 Vector2f smokePosition = new Vector2f();
095
096 private float smokeAccumulator = 0;
097 private float smokeGenSpeed = 130f;
098 private static final float SMOKE_LIMIT = 5;
099
100 Vector2f oldPosition = new Vector2f();
101 int framesCounter = 0;
102 @Override
103 public void update()
104 {
105 oldPosition.x = position.x;
106 oldPosition.y = position.y;
107 interpolate(position,speed);
108 if (frozen)
109 return;
110
111
112 smokeAccumulator += smokeGenSpeed * tick;
113
114 if (smokeAccumulator > SMOKE_LIMIT)
115 {
116 smoke = new Smoke();
117 //smoke.setRatio(smokeAccumulator/SMOKE_LIMIT );
118 smokePosition.x = position.x -15 ;
119 //smokePosition.x = (Prototyp.random.nextInt(1) == 0)? smokePosition.x: -smokePosition.x;
120 smokePosition.y = Prototyp.random.nextInt(5);
121 smokePosition.y = (Prototyp.random.nextInt(2) == 0)? smokePosition.y: -smokePosition.y;
122 smokePosition.y += position.y -5;
123 smoke.spawn(smokePosition,Prototyp.DEFAULT_SCROLLING_SPEED,Prototyp.fx);
124 smokeAccumulator=0;
125 }
126 if (this.position.x - this.width > (Prototyp.SCREEN_WIDTH / 2) || this.position.x + this.width < - (Prototyp.SCREEN_WIDTH / 2))
127 {
128 unSpawn();
129 if (Logger.isLogActivate) Logger.log(this.getClass().getName()+" died");
130 return;
131 }
132
133 // Modify direction
134
135 float speedAngleInRadians = 0;
136 float targetAngleInRadians = 0;
137 float angleDifferenceInRadians = 0;
138 float angleToAdd = 0;
139
140 Vector2f targetCooRelativeToThis = new Vector2f();
141
142 if (target.life <= 0)
143 acquiereNewTarget(target.getLayer());
144 if (target == null)
145 return;
146
147 targetCooRelativeToThis.x = target.position.x - this.position.x ;
148 targetCooRelativeToThis.y = target.position.y - this.position.y;
149
150
151 speedAngleInRadians = (float)Math.atan2(speed.y,speed.x);
152 if (speedAngleInRadians < 0)
153 speedAngleInRadians += 2 * Math.PI;
154
155 targetAngleInRadians= (float)Math.atan2(targetCooRelativeToThis.y,targetCooRelativeToThis.x);
156 if (targetAngleInRadians < 0)
157 targetAngleInRadians += 2 * Math.PI;
158
159 if ( speedAngleInRadians > targetAngleInRadians)
160 {
161 angleDifferenceInRadians = speedAngleInRadians - targetAngleInRadians;
162 angleDifferenceInRadians = -angleDifferenceInRadians;
163 }
164 else
165 {
166 angleDifferenceInRadians = targetAngleInRadians-speedAngleInRadians;
167
168 }
169
170
171
172 if (Math.abs(angleDifferenceInRadians) > maxRadianManiability)
173 {
174 angleToAdd = maxRadianManiability ;
175 if (angleDifferenceInRadians < 0)
176 angleToAdd = -angleToAdd;
177 }
178 else
179 angleToAdd = angleDifferenceInRadians;
180
181
182 GLUTILS.rotateAroundZ(this.speed,angleToAdd);
183 this.rotation += GLUTILS.radiansToDegres(angleToAdd);
184
185 }
186
187 @Override
188 public boolean collided(Entity entity)
189 {
190 this.life = -1;
191 if (this.life <= 0)
192 {
193 this.unSpawn();
194 ex = new Explosion(Prototyp.random.nextInt(2)+IEntity.EXPLOSION1);
195 ex.spawn(this.position,speedNull,Prototyp.frontground);
196 return true;
197 }
198 return false;
199 }
200
201 }
|