001 package com.croftsoft.apps.chat.model.seri; 002 003 import java.awt.Shape; 004 005 import com.croftsoft.core.animation.model.ModelId; 006 import com.croftsoft.core.animation.model.seri.SeriModel; 007 import com.croftsoft.core.math.geom.Circle; 008 import com.croftsoft.core.math.geom.Point2DD; 009 import com.croftsoft.core.math.geom.PointXY; 010 import com.croftsoft.core.lang.NullArgumentException; 011 import com.croftsoft.core.util.consumer.Consumer; 012 013 import com.croftsoft.apps.chat.ChatConstants; 014 import com.croftsoft.apps.chat.event.MoveEvent; 015 import com.croftsoft.apps.chat.model.ChatModel; 016 import com.croftsoft.apps.chat.model.ChatWorld; 017 018 /********************************************************************* 019 * The base class for a game world object Model. 020 * 021 * @version 022 * 2003-06-17 023 * @since 024 * 2003-06-05 025 * @author 026 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 027 *********************************************************************/ 028 029 public class SeriChatModel 030 extends SeriModel 031 implements ChatModel 032 ////////////////////////////////////////////////////////////////////// 033 ////////////////////////////////////////////////////////////////////// 034 { 035 036 private static final long serialVersionUID = 0L; 037 038 // 039 040 private final String avatarType; 041 042 private final Circle circle; 043 044 // 045 046 private transient ChatWorld chatWorld; 047 048 private transient Consumer eventConsumer; 049 050 // 051 052 private PointXY destination; 053 054 private boolean updated; 055 056 private boolean active; 057 058 ////////////////////////////////////////////////////////////////////// 059 ////////////////////////////////////////////////////////////////////// 060 061 public SeriChatModel ( 062 ModelId modelId, 063 Consumer eventConsumer, 064 ChatWorld chatWorld, 065 String avatarType, 066 double x, 067 double y ) 068 ////////////////////////////////////////////////////////////////////// 069 { 070 super ( modelId ); 071 072 setEventConsumer ( eventConsumer ); 073 074 NullArgumentException.check ( this.chatWorld = chatWorld ); 075 076 NullArgumentException.check ( this.avatarType = avatarType ); 077 078 circle = new Circle ( x, y, ChatConstants.RADIUS ); 079 080 active = true; 081 } 082 083 ////////////////////////////////////////////////////////////////////// 084 ////////////////////////////////////////////////////////////////////// 085 086 public String getAvatarType ( ) { return avatarType; } 087 088 ////////////////////////////////////////////////////////////////////// 089 ////////////////////////////////////////////////////////////////////// 090 091 public boolean isActive ( ) { return active; } 092 093 public double getCenterX ( ) { return circle.getCenterX ( ); } 094 095 public double getCenterY ( ) { return circle.getCenterY ( ); } 096 097 public Shape getShape ( ) { return circle; } 098 099 public boolean isUpdated ( ) { return updated; } 100 101 public double getZ ( ) { return 0.0; } 102 103 ////////////////////////////////////////////////////////////////////// 104 ////////////////////////////////////////////////////////////////////// 105 106 public void setActive ( boolean active ) 107 ////////////////////////////////////////////////////////////////////// 108 { 109 this.active = active; 110 } 111 112 public void setDestination ( PointXY destination ) 113 ////////////////////////////////////////////////////////////////////// 114 { 115 if ( destination != null ) 116 { 117 destination = new Point2DD ( destination ); 118 } 119 120 this.destination = destination; 121 122 eventConsumer.consume ( 123 new MoveEvent ( modelId, circle.getCenter ( ), destination ) ); 124 } 125 126 public void setEventConsumer ( Consumer eventConsumer ) 127 ////////////////////////////////////////////////////////////////////// 128 { 129 NullArgumentException.check ( this.eventConsumer = eventConsumer ); 130 } 131 132 ////////////////////////////////////////////////////////////////////// 133 ////////////////////////////////////////////////////////////////////// 134 135 public void setCenter ( 136 double x, 137 double y ) 138 ////////////////////////////////////////////////////////////////////// 139 { 140 circle.setCenter ( x, y ); 141 142 updated = true; 143 } 144 145 public void prepare ( ) 146 ////////////////////////////////////////////////////////////////////// 147 { 148 updated = false; 149 } 150 151 public void update ( double timeDelta ) 152 ////////////////////////////////////////////////////////////////////// 153 { 154 updatePosition ( timeDelta ); 155 } 156 157 ////////////////////////////////////////////////////////////////////// 158 ////////////////////////////////////////////////////////////////////// 159 160 private void updatePosition ( double timeDelta ) 161 ////////////////////////////////////////////////////////////////////// 162 { 163 if ( destination == null ) 164 { 165 return; 166 } 167 168 PointXY center = circle.getCenter ( ); 169 170 double centerX = center.getX ( ); 171 172 double centerY = center.getY ( ); 173 174 double deltaX = destination.getX ( ) - centerX; 175 176 double deltaY = destination.getY ( ) - centerY; 177 178 if ( ( deltaX == 0.0 ) 179 && ( deltaY == 0.0 ) ) 180 { 181 destination = null; 182 183 return; 184 } 185 186 double aimHeading = Math.atan2 ( deltaY, deltaX ); 187 188 if ( aimHeading < 0.0 ) 189 { 190 aimHeading += 2.0 * Math.PI; 191 } 192 193 double moveX 194 = timeDelta * ChatConstants.SPEED * Math.cos ( aimHeading ); 195 196 double moveY 197 = timeDelta * ChatConstants.SPEED * Math.sin ( aimHeading ); 198 199 if ( Math.abs ( moveX ) > Math.abs ( deltaX ) ) 200 { 201 moveX = deltaX; 202 } 203 204 if ( Math.abs ( moveY ) > Math.abs ( deltaY ) ) 205 { 206 moveY = deltaY; 207 } 208 209 double newX = centerX + moveX; 210 211 double newY = centerY + moveY; 212 213 circle.setCenter ( newX, newY ); 214 215 if ( ( chatWorld == null ) 216 || !chatWorld.isBlocked ( circle, this ) ) 217 { 218 updated = true; 219 } 220 else 221 { 222 circle.setCenter ( centerX, centerY ); 223 224 if ( chatWorld.isBlocked ( circle, this ) ) 225 { 226 circle.setCenter ( newX, newY ); 227 228 updated = true; 229 } 230 else 231 { 232 setDestination ( null ); 233 } 234 } 235 } 236 237 ////////////////////////////////////////////////////////////////////// 238 ////////////////////////////////////////////////////////////////////// 239 }